mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-26 00:41:17 +00:00
generic: 6.6: backport upstream RealTek PHY patches
Replace downstream RealTek PHY patches with backported ones. Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
This commit is contained in:
parent
f20987c161
commit
ca4469045f
@ -0,0 +1,30 @@
|
|||||||
|
From 6c06c88fa838fcc1b7e5380facd086f57fd9d1c4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Sun, 4 Feb 2024 15:16:46 +0100
|
||||||
|
Subject: [PATCH] net: mdio: add 2.5g and 5g related PMA speed constants
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Add constants indicating 2.5g and 5g ability in the MMD PMA speed
|
||||||
|
register.
|
||||||
|
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||||
|
Link: https://lore.kernel.org/r/98e15038-d96c-442f-93e4-410100d27866@gmail.com
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
include/uapi/linux/mdio.h | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
--- a/include/uapi/linux/mdio.h
|
||||||
|
+++ b/include/uapi/linux/mdio.h
|
||||||
|
@@ -138,6 +138,8 @@
|
||||||
|
#define MDIO_PMA_SPEED_1000 0x0010 /* 1000M capable */
|
||||||
|
#define MDIO_PMA_SPEED_100 0x0020 /* 100M capable */
|
||||||
|
#define MDIO_PMA_SPEED_10 0x0040 /* 10M capable */
|
||||||
|
+#define MDIO_PMA_SPEED_2_5G 0x2000 /* 2.5G capable */
|
||||||
|
+#define MDIO_PMA_SPEED_5G 0x4000 /* 5G capable */
|
||||||
|
#define MDIO_PCS_SPEED_10P2B 0x0002 /* 10PASS-TS/2BASE-TL capable */
|
||||||
|
#define MDIO_PCS_SPEED_2_5G 0x0040 /* 2.5G capable */
|
||||||
|
#define MDIO_PCS_SPEED_5G 0x0080 /* 5G capable */
|
@ -0,0 +1,40 @@
|
|||||||
|
From 5befa3728b855e9f75b29bb0069a1ca7f5bab2f7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||||
|
Date: Wed, 31 Jan 2024 21:24:29 +0100
|
||||||
|
Subject: [PATCH] net: phy: realtek: add support for RTL8126A-integrated 5Gbps
|
||||||
|
PHY
|
||||||
|
|
||||||
|
A user reported that first consumer mainboards show up with a RTL8126A
|
||||||
|
5Gbps MAC/PHY. This adds support for the integrated PHY, which is also
|
||||||
|
available stand-alone. From a PHY driver perspective it's treated the
|
||||||
|
same as the 2.5Gbps PHY's, we just have to support the new PHY ID.
|
||||||
|
|
||||||
|
Reported-by: Joe Salmeri <jmscdba@gmail.com>
|
||||||
|
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||||
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Joe Salmeri <jmscdba@gmail.com>
|
||||||
|
Link: https://lore.kernel.org/r/0c8e67ea-6505-43d1-bd51-94e7ecd6e222@gmail.com
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/phy/realtek.c | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/realtek.c
|
||||||
|
+++ b/drivers/net/phy/realtek.c
|
||||||
|
@@ -1050,6 +1050,16 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.read_page = rtl821x_read_page,
|
||||||
|
.write_page = rtl821x_write_page,
|
||||||
|
}, {
|
||||||
|
+ PHY_ID_MATCH_EXACT(0x001cc862),
|
||||||
|
+ .name = "RTL8251B 5Gbps PHY",
|
||||||
|
+ .get_features = rtl822x_get_features,
|
||||||
|
+ .config_aneg = rtl822x_config_aneg,
|
||||||
|
+ .read_status = rtl822x_read_status,
|
||||||
|
+ .suspend = genphy_suspend,
|
||||||
|
+ .resume = rtlgen_resume,
|
||||||
|
+ .read_page = rtl821x_read_page,
|
||||||
|
+ .write_page = rtl821x_write_page,
|
||||||
|
+ }, {
|
||||||
|
PHY_ID_MATCH_EXACT(0x001cc961),
|
||||||
|
.name = "RTL8366RB Gigabit Ethernet",
|
||||||
|
.config_init = &rtl8366rb_config_init,
|
@ -0,0 +1,93 @@
|
|||||||
|
From 2b9ec5dfb8255656ca731ab9d9bf59d94566d377 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Sun, 4 Feb 2024 15:17:53 +0100
|
||||||
|
Subject: [PATCH] net: phy: realtek: use generic MDIO constants
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Drop the ad-hoc MDIO constants used in the driver and use generic
|
||||||
|
constants instead.
|
||||||
|
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||||
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Link: https://lore.kernel.org/r/732a70d6-4191-4aae-8862-3716b062aa9e@gmail.com
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/phy/realtek.c | 30 +++++++++++++-----------------
|
||||||
|
1 file changed, 13 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/realtek.c
|
||||||
|
+++ b/drivers/net/phy/realtek.c
|
||||||
|
@@ -57,14 +57,6 @@
|
||||||
|
#define RTL8366RB_POWER_SAVE 0x15
|
||||||
|
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||||
|
|
||||||
|
-#define RTL_SUPPORTS_5000FULL BIT(14)
|
||||||
|
-#define RTL_SUPPORTS_2500FULL BIT(13)
|
||||||
|
-#define RTL_SUPPORTS_10000FULL BIT(0)
|
||||||
|
-#define RTL_ADV_2500FULL BIT(7)
|
||||||
|
-#define RTL_LPADV_10000FULL BIT(11)
|
||||||
|
-#define RTL_LPADV_5000FULL BIT(6)
|
||||||
|
-#define RTL_LPADV_2500FULL BIT(5)
|
||||||
|
-
|
||||||
|
#define RTL9000A_GINMR 0x14
|
||||||
|
#define RTL9000A_GINMR_LINK_STATUS BIT(4)
|
||||||
|
|
||||||
|
@@ -676,11 +668,11 @@ static int rtl822x_get_features(struct p
|
||||||
|
return val;
|
||||||
|
|
||||||
|
linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||||
|
- phydev->supported, val & RTL_SUPPORTS_2500FULL);
|
||||||
|
+ phydev->supported, val & MDIO_PMA_SPEED_2_5G);
|
||||||
|
linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
|
||||||
|
- phydev->supported, val & RTL_SUPPORTS_5000FULL);
|
||||||
|
+ phydev->supported, val & MDIO_PMA_SPEED_5G);
|
||||||
|
linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
|
||||||
|
- phydev->supported, val & RTL_SUPPORTS_10000FULL);
|
||||||
|
+ phydev->supported, val & MDIO_SPEED_10G);
|
||||||
|
|
||||||
|
return genphy_read_abilities(phydev);
|
||||||
|
}
|
||||||
|
@@ -694,10 +686,11 @@ static int rtl822x_config_aneg(struct ph
|
||||||
|
|
||||||
|
if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||||
|
phydev->advertising))
|
||||||
|
- adv2500 = RTL_ADV_2500FULL;
|
||||||
|
+ adv2500 = MDIO_AN_10GBT_CTRL_ADV2_5G;
|
||||||
|
|
||||||
|
ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
|
||||||
|
- RTL_ADV_2500FULL, adv2500);
|
||||||
|
+ MDIO_AN_10GBT_CTRL_ADV2_5G,
|
||||||
|
+ adv2500);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -716,11 +709,14 @@ static int rtl822x_read_status(struct ph
|
||||||
|
return lpadv;
|
||||||
|
|
||||||
|
linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
|
||||||
|
- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
|
||||||
|
+ phydev->lp_advertising,
|
||||||
|
+ lpadv & MDIO_AN_10GBT_STAT_LP10G);
|
||||||
|
linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
|
||||||
|
- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
|
||||||
|
+ phydev->lp_advertising,
|
||||||
|
+ lpadv & MDIO_AN_10GBT_STAT_LP5G);
|
||||||
|
linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||||
|
- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
|
||||||
|
+ phydev->lp_advertising,
|
||||||
|
+ lpadv & MDIO_AN_10GBT_STAT_LP2_5G);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = genphy_read_status(phydev);
|
||||||
|
@@ -738,7 +734,7 @@ static bool rtlgen_supports_2_5gbps(stru
|
||||||
|
val = phy_read(phydev, 0x13);
|
||||||
|
phy_write(phydev, RTL821x_PAGE_SELECT, 0);
|
||||||
|
|
||||||
|
- return val >= 0 && val & RTL_SUPPORTS_2500FULL;
|
||||||
|
+ return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtlgen_match_phy_device(struct phy_device *phydev)
|
@ -0,0 +1,42 @@
|
|||||||
|
From db1bb7741ff29bf2cefcbc0ca567644e9ed1caa9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||||
|
Date: Sun, 4 Feb 2024 15:18:50 +0100
|
||||||
|
Subject: [PATCH] net: phy: realtek: add 5Gbps support to rtl822x_config_aneg()
|
||||||
|
|
||||||
|
RTL8126 as an evolution of RTL8125 supports 5Gbps. rtl822x_config_aneg()
|
||||||
|
is used by the PHY driver for the integrated PHY, therefore add 5Gbps
|
||||||
|
support to it.
|
||||||
|
|
||||||
|
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||||
|
Link: https://lore.kernel.org/r/5644ab50-e3e9-477c-96db-05cd5bdc2563@gmail.com
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/phy/realtek.c | 12 ++++++++----
|
||||||
|
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/realtek.c
|
||||||
|
+++ b/drivers/net/phy/realtek.c
|
||||||
|
@@ -682,15 +682,19 @@ static int rtl822x_config_aneg(struct ph
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (phydev->autoneg == AUTONEG_ENABLE) {
|
||||||
|
- u16 adv2500 = 0;
|
||||||
|
+ u16 adv = 0;
|
||||||
|
|
||||||
|
if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||||
|
phydev->advertising))
|
||||||
|
- adv2500 = MDIO_AN_10GBT_CTRL_ADV2_5G;
|
||||||
|
+ adv |= MDIO_AN_10GBT_CTRL_ADV2_5G;
|
||||||
|
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
|
||||||
|
+ phydev->advertising))
|
||||||
|
+ adv |= MDIO_AN_10GBT_CTRL_ADV5G;
|
||||||
|
|
||||||
|
ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
|
||||||
|
- MDIO_AN_10GBT_CTRL_ADV2_5G,
|
||||||
|
- adv2500);
|
||||||
|
+ MDIO_AN_10GBT_CTRL_ADV2_5G |
|
||||||
|
+ MDIO_AN_10GBT_CTRL_ADV5G,
|
||||||
|
+ adv);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
From b63cc73341e076961d564a74cc3d29b2fd444079 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||||
|
Date: Thu, 8 Feb 2024 07:59:18 +0100
|
||||||
|
Subject: [PATCH] net: phy: realtek: use generic MDIO helpers to simplify the
|
||||||
|
code
|
||||||
|
|
||||||
|
Use generic MDIO helpers to simplify the code.
|
||||||
|
|
||||||
|
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||||
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Link: https://lore.kernel.org/r/422ae70f-7305-45fd-ab3e-0dd604b9fd6c@gmail.com
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/net/phy/realtek.c | 20 +++-----------------
|
||||||
|
1 file changed, 3 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/realtek.c
|
||||||
|
+++ b/drivers/net/phy/realtek.c
|
||||||
|
@@ -682,14 +682,7 @@ static int rtl822x_config_aneg(struct ph
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (phydev->autoneg == AUTONEG_ENABLE) {
|
||||||
|
- u16 adv = 0;
|
||||||
|
-
|
||||||
|
- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||||
|
- phydev->advertising))
|
||||||
|
- adv |= MDIO_AN_10GBT_CTRL_ADV2_5G;
|
||||||
|
- if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
|
||||||
|
- phydev->advertising))
|
||||||
|
- adv |= MDIO_AN_10GBT_CTRL_ADV5G;
|
||||||
|
+ u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
|
||||||
|
|
||||||
|
ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
|
||||||
|
MDIO_AN_10GBT_CTRL_ADV2_5G |
|
||||||
|
@@ -712,15 +705,8 @@ static int rtl822x_read_status(struct ph
|
||||||
|
if (lpadv < 0)
|
||||||
|
return lpadv;
|
||||||
|
|
||||||
|
- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
|
||||||
|
- phydev->lp_advertising,
|
||||||
|
- lpadv & MDIO_AN_10GBT_STAT_LP10G);
|
||||||
|
- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
|
||||||
|
- phydev->lp_advertising,
|
||||||
|
- lpadv & MDIO_AN_10GBT_STAT_LP5G);
|
||||||
|
- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||||
|
- phydev->lp_advertising,
|
||||||
|
- lpadv & MDIO_AN_10GBT_STAT_LP2_5G);
|
||||||
|
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
|
||||||
|
+ lpadv);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = genphy_read_status(phydev);
|
@ -0,0 +1,209 @@
|
|||||||
|
From deb8af5243504e379878ae3f9a091b21422d65b2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexander Couzens <lynxis@fe80.eu>
|
||||||
|
Date: Tue, 9 Apr 2024 09:30:11 +0200
|
||||||
|
Subject: [PATCH] net: phy: realtek: configure SerDes mode for rtl822xb PHYs
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The rtl8221b and rtl8226b series support switching SerDes mode between
|
||||||
|
2500base-x and sgmii based on the negotiated copper speed.
|
||||||
|
|
||||||
|
Configure this switching mode according to SerDes modes supported by
|
||||||
|
host.
|
||||||
|
|
||||||
|
There is an additional datasheet for RTL8226B/RTL8221B called
|
||||||
|
"SERDES MODE SETTING FLOW APPLICATION NOTE" where a sequence is
|
||||||
|
described to setup interface and rate adapter mode.
|
||||||
|
|
||||||
|
However, there is no documentation about the meaning of registers
|
||||||
|
and bits, it's literally just magic numbers and pseudo-code.
|
||||||
|
|
||||||
|
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
||||||
|
[ refactored, dropped HiSGMII mode and changed commit message ]
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
[ changed rtl822x_update_interface() to use vendor register ]
|
||||||
|
[ always fill in possible interfaces ]
|
||||||
|
[ only apply to rtl8221b and rtl8226b phy's ]
|
||||||
|
[ set phydev->rate_matching in .config_init() ]
|
||||||
|
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
|
||||||
|
|
||||||
|
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||||
|
Reviewed-by: should come before them, without any blank lines. As the
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/phy/realtek.c | 114 ++++++++++++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 110 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/realtek.c
|
||||||
|
+++ b/drivers/net/phy/realtek.c
|
||||||
|
@@ -54,6 +54,16 @@
|
||||||
|
RTL8201F_ISR_LINK)
|
||||||
|
#define RTL8201F_IER 0x13
|
||||||
|
|
||||||
|
+#define RTL822X_VND1_SERDES_OPTION 0x697a
|
||||||
|
+#define RTL822X_VND1_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
|
||||||
|
+#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII 0
|
||||||
|
+#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX 2
|
||||||
|
+
|
||||||
|
+#define RTL822X_VND1_SERDES_CTRL3 0x7580
|
||||||
|
+#define RTL822X_VND1_SERDES_CTRL3_MODE_MASK GENMASK(5, 0)
|
||||||
|
+#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
|
||||||
|
+#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
|
||||||
|
+
|
||||||
|
#define RTL8366RB_POWER_SAVE 0x15
|
||||||
|
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||||
|
|
||||||
|
@@ -659,6 +669,63 @@ static int rtl822x_write_mmd(struct phy_
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int rtl822xb_config_init(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ bool has_2500, has_sgmii;
|
||||||
|
+ u16 mode;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
|
||||||
|
+ phydev->host_interfaces) ||
|
||||||
|
+ phydev->interface == PHY_INTERFACE_MODE_2500BASEX;
|
||||||
|
+
|
||||||
|
+ has_sgmii = test_bit(PHY_INTERFACE_MODE_SGMII,
|
||||||
|
+ phydev->host_interfaces) ||
|
||||||
|
+ phydev->interface == PHY_INTERFACE_MODE_SGMII;
|
||||||
|
+
|
||||||
|
+ /* fill in possible interfaces */
|
||||||
|
+ __assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces,
|
||||||
|
+ has_2500);
|
||||||
|
+ __assign_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces,
|
||||||
|
+ has_sgmii);
|
||||||
|
+
|
||||||
|
+ if (!has_2500 && !has_sgmii)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* determine SerDes option mode */
|
||||||
|
+ if (has_2500 && !has_sgmii) {
|
||||||
|
+ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX;
|
||||||
|
+ phydev->rate_matching = RATE_MATCH_PAUSE;
|
||||||
|
+ } else {
|
||||||
|
+ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII;
|
||||||
|
+ phydev->rate_matching = RATE_MATCH_NONE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* the following sequence with magic numbers sets up the SerDes
|
||||||
|
+ * option mode
|
||||||
|
+ */
|
||||||
|
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND1,
|
||||||
|
+ RTL822X_VND1_SERDES_OPTION,
|
||||||
|
+ RTL822X_VND1_SERDES_OPTION_MODE_MASK,
|
||||||
|
+ mode);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int rtl822x_get_features(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
@@ -695,6 +762,28 @@ static int rtl822x_config_aneg(struct ph
|
||||||
|
return __genphy_config_aneg(phydev, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void rtl822xb_update_interface(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int val;
|
||||||
|
+
|
||||||
|
+ if (!phydev->link)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Change interface according to serdes mode */
|
||||||
|
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CTRL3);
|
||||||
|
+ if (val < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ switch (val & RTL822X_VND1_SERDES_CTRL3_MODE_MASK) {
|
||||||
|
+ case RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX:
|
||||||
|
+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||||
|
+ break;
|
||||||
|
+ case RTL822X_VND1_SERDES_CTRL3_MODE_SGMII:
|
||||||
|
+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int rtl822x_read_status(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
@@ -716,6 +805,19 @@ static int rtl822x_read_status(struct ph
|
||||||
|
return rtlgen_get_speed(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int rtl822xb_read_status(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = rtl822x_read_status(phydev);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ rtl822xb_update_interface(phydev);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
@@ -988,7 +1090,8 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
- .read_status = rtl822x_read_status,
|
||||||
|
+ .config_init = rtl822xb_config_init,
|
||||||
|
+ .read_status = rtl822xb_read_status,
|
||||||
|
.suspend = genphy_suspend,
|
||||||
|
.resume = rtlgen_resume,
|
||||||
|
.read_page = rtl821x_read_page,
|
||||||
|
@@ -1010,7 +1113,8 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
- .read_status = rtl822x_read_status,
|
||||||
|
+ .config_init = rtl822xb_config_init,
|
||||||
|
+ .read_status = rtl822xb_read_status,
|
||||||
|
.suspend = genphy_suspend,
|
||||||
|
.resume = rtlgen_resume,
|
||||||
|
.read_page = rtl821x_read_page,
|
||||||
|
@@ -1020,7 +1124,8 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.name = "RTL8221B-VB-CG 2.5Gbps PHY",
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
- .read_status = rtl822x_read_status,
|
||||||
|
+ .config_init = rtl822xb_config_init,
|
||||||
|
+ .read_status = rtl822xb_read_status,
|
||||||
|
.suspend = genphy_suspend,
|
||||||
|
.resume = rtlgen_resume,
|
||||||
|
.read_page = rtl821x_read_page,
|
||||||
|
@@ -1030,7 +1135,8 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.name = "RTL8221B-VM-CG 2.5Gbps PHY",
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
- .read_status = rtl822x_read_status,
|
||||||
|
+ .config_init = rtl822xb_config_init,
|
||||||
|
+ .read_status = rtl822xb_read_status,
|
||||||
|
.suspend = genphy_suspend,
|
||||||
|
.resume = rtlgen_resume,
|
||||||
|
.read_page = rtl821x_read_page,
|
@ -0,0 +1,77 @@
|
|||||||
|
From c189dbd738243be6775bb6878366bf63e27bfd05 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eric Woudstra <ericwouds@gmail.com>
|
||||||
|
Date: Tue, 9 Apr 2024 09:30:12 +0200
|
||||||
|
Subject: [PATCH] net: phy: realtek: add get_rate_matching() for rtl822xb PHYs
|
||||||
|
|
||||||
|
Uses vendor register to determine if SerDes is setup in rate-matching mode.
|
||||||
|
|
||||||
|
Rate-matching only supported when SerDes is set to 2500base-x.
|
||||||
|
|
||||||
|
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/phy/realtek.c | 25 +++++++++++++++++++++++++
|
||||||
|
1 file changed, 25 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/realtek.c
|
||||||
|
+++ b/drivers/net/phy/realtek.c
|
||||||
|
@@ -726,6 +726,27 @@ static int rtl822xb_config_init(struct p
|
||||||
|
return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int rtl822xb_get_rate_matching(struct phy_device *phydev,
|
||||||
|
+ phy_interface_t iface)
|
||||||
|
+{
|
||||||
|
+ int val;
|
||||||
|
+
|
||||||
|
+ /* Only rate matching at 2500base-x */
|
||||||
|
+ if (iface != PHY_INTERFACE_MODE_2500BASEX)
|
||||||
|
+ return RATE_MATCH_NONE;
|
||||||
|
+
|
||||||
|
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_OPTION);
|
||||||
|
+ if (val < 0)
|
||||||
|
+ return val;
|
||||||
|
+
|
||||||
|
+ if ((val & RTL822X_VND1_SERDES_OPTION_MODE_MASK) ==
|
||||||
|
+ RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX)
|
||||||
|
+ return RATE_MATCH_PAUSE;
|
||||||
|
+
|
||||||
|
+ /* RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII */
|
||||||
|
+ return RATE_MATCH_NONE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int rtl822x_get_features(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
@@ -1091,6 +1112,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
+ .get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
.read_status = rtl822xb_read_status,
|
||||||
|
.suspend = genphy_suspend,
|
||||||
|
.resume = rtlgen_resume,
|
||||||
|
@@ -1114,6 +1136,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
+ .get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
.read_status = rtl822xb_read_status,
|
||||||
|
.suspend = genphy_suspend,
|
||||||
|
.resume = rtlgen_resume,
|
||||||
|
@@ -1125,6 +1148,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
+ .get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
.read_status = rtl822xb_read_status,
|
||||||
|
.suspend = genphy_suspend,
|
||||||
|
.resume = rtlgen_resume,
|
||||||
|
@@ -1136,6 +1160,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
+ .get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
.read_status = rtl822xb_read_status,
|
||||||
|
.suspend = genphy_suspend,
|
||||||
|
.resume = rtlgen_resume,
|
@ -0,0 +1,218 @@
|
|||||||
|
From ad5ce743a6b0329f642d80be50ef7b534e908fba Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Tue, 9 Apr 2024 09:30:13 +0200
|
||||||
|
Subject: [PATCH] net: phy: realtek: Add driver instances for rtl8221b via
|
||||||
|
Clause 45
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Collected from several commits in [PATCH net-next]
|
||||||
|
"Realtek RTL822x PHY rework to c45 and SerDes interface switching"
|
||||||
|
|
||||||
|
The instances are used by Clause 45 only accessible PHY's on several sfp
|
||||||
|
modules, which are using RollBall protocol.
|
||||||
|
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
[ Added matching functions to differentiate C45 instances ]
|
||||||
|
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
|
||||||
|
|
||||||
|
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/phy/realtek.c | 135 ++++++++++++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 131 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/realtek.c
|
||||||
|
+++ b/drivers/net/phy/realtek.c
|
||||||
|
@@ -64,6 +64,13 @@
|
||||||
|
#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
|
||||||
|
#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
|
||||||
|
|
||||||
|
+/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
|
||||||
|
+ * is set, they cannot be accessed by C45-over-C22.
|
||||||
|
+ */
|
||||||
|
+#define RTL822X_VND2_GBCR 0xa412
|
||||||
|
+
|
||||||
|
+#define RTL822X_VND2_GANLPAR 0xa414
|
||||||
|
+
|
||||||
|
#define RTL8366RB_POWER_SAVE 0x15
|
||||||
|
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||||
|
|
||||||
|
@@ -74,6 +81,9 @@
|
||||||
|
|
||||||
|
#define RTL_GENERIC_PHYID 0x001cc800
|
||||||
|
#define RTL_8211FVD_PHYID 0x001cc878
|
||||||
|
+#define RTL_8221B_VB_CG 0x001cc849
|
||||||
|
+#define RTL_8221B_VN_CG 0x001cc84a
|
||||||
|
+#define RTL_8251B 0x001cc862
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("Realtek PHY driver");
|
||||||
|
MODULE_AUTHOR("Johnson Leung");
|
||||||
|
@@ -839,6 +849,67 @@ static int rtl822xb_read_status(struct p
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int rtl822x_c45_config_aneg(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ bool changed = false;
|
||||||
|
+ int ret, val;
|
||||||
|
+
|
||||||
|
+ if (phydev->autoneg == AUTONEG_DISABLE)
|
||||||
|
+ return genphy_c45_pma_setup_forced(phydev);
|
||||||
|
+
|
||||||
|
+ ret = genphy_c45_an_config_aneg(phydev);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+ if (ret > 0)
|
||||||
|
+ changed = true;
|
||||||
|
+
|
||||||
|
+ val = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
|
||||||
|
+
|
||||||
|
+ /* Vendor register as C45 has no standardized support for 1000BaseT */
|
||||||
|
+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL822X_VND2_GBCR,
|
||||||
|
+ ADVERTISE_1000FULL, val);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+ if (ret > 0)
|
||||||
|
+ changed = true;
|
||||||
|
+
|
||||||
|
+ return genphy_c45_check_and_restart_aneg(phydev, changed);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int rtl822x_c45_read_status(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int ret, val;
|
||||||
|
+
|
||||||
|
+ ret = genphy_c45_read_status(phydev);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* Vendor register as C45 has no standardized support for 1000BaseT */
|
||||||
|
+ if (phydev->autoneg == AUTONEG_ENABLE) {
|
||||||
|
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
|
||||||
|
+ RTL822X_VND2_GANLPAR);
|
||||||
|
+ if (val < 0)
|
||||||
|
+ return val;
|
||||||
|
+
|
||||||
|
+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int rtl822xb_c45_read_status(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = rtl822x_c45_read_status(phydev);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ rtl822xb_update_interface(phydev);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
@@ -862,6 +933,35 @@ static int rtl8226_match_phy_device(stru
|
||||||
|
rtlgen_supports_2_5gbps(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
|
||||||
|
+ bool is_c45)
|
||||||
|
+{
|
||||||
|
+ if (phydev->is_c45)
|
||||||
|
+ return is_c45 && (id == phydev->c45_ids.device_ids[1]);
|
||||||
|
+ else
|
||||||
|
+ return !is_c45 && (id == phydev->phy_id);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int rtlgen_resume(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int ret = genphy_resume(phydev);
|
||||||
|
@@ -872,6 +972,15 @@ static int rtlgen_resume(struct phy_devi
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int rtlgen_c45_resume(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ int ret = genphy_c45_pma_resume(phydev);
|
||||||
|
+
|
||||||
|
+ msleep(20);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int rtl9000a_config_init(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
phydev->autoneg = AUTONEG_DISABLE;
|
||||||
|
@@ -1143,8 +1252,8 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.read_page = rtl821x_read_page,
|
||||||
|
.write_page = rtl821x_write_page,
|
||||||
|
}, {
|
||||||
|
- PHY_ID_MATCH_EXACT(0x001cc849),
|
||||||
|
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
|
||||||
|
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||||
|
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
@@ -1155,8 +1264,17 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.read_page = rtl821x_read_page,
|
||||||
|
.write_page = rtl821x_write_page,
|
||||||
|
}, {
|
||||||
|
- PHY_ID_MATCH_EXACT(0x001cc84a),
|
||||||
|
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
|
||||||
|
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||||
|
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||||
|
+ .config_init = rtl822xb_config_init,
|
||||||
|
+ .get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
+ .config_aneg = rtl822x_c45_config_aneg,
|
||||||
|
+ .read_status = rtl822xb_c45_read_status,
|
||||||
|
+ .suspend = genphy_c45_pma_suspend,
|
||||||
|
+ .resume = rtlgen_c45_resume,
|
||||||
|
+ }, {
|
||||||
|
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||||
|
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
@@ -1167,6 +1285,15 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.read_page = rtl821x_read_page,
|
||||||
|
.write_page = rtl821x_write_page,
|
||||||
|
}, {
|
||||||
|
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||||
|
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||||
|
+ .config_init = rtl822xb_config_init,
|
||||||
|
+ .get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
+ .config_aneg = rtl822x_c45_config_aneg,
|
||||||
|
+ .read_status = rtl822xb_c45_read_status,
|
||||||
|
+ .suspend = genphy_c45_pma_suspend,
|
||||||
|
+ .resume = rtlgen_c45_resume,
|
||||||
|
+ }, {
|
||||||
|
PHY_ID_MATCH_EXACT(0x001cc862),
|
||||||
|
.name = "RTL8251B 5Gbps PHY",
|
||||||
|
.get_features = rtl822x_get_features,
|
@ -0,0 +1,125 @@
|
|||||||
|
From 2e4ea707c7e04eb83e58c43e0e744bbdf6b23ff2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eric Woudstra <ericwouds@gmail.com>
|
||||||
|
Date: Tue, 9 Apr 2024 09:30:14 +0200
|
||||||
|
Subject: [PATCH] net: phy: realtek: Change rtlgen_get_speed() to
|
||||||
|
rtlgen_decode_speed()
|
||||||
|
|
||||||
|
The value of the register to determine the speed, is retrieved
|
||||||
|
differently when using Clause 45 only. To use the rtlgen_get_speed()
|
||||||
|
function in this case, pass the value of the register as argument to
|
||||||
|
rtlgen_get_speed(). The function would then always return 0, so change it
|
||||||
|
to void. A better name for this function now is rtlgen_decode_speed().
|
||||||
|
|
||||||
|
Replace a call to genphy_read_status() followed by rtlgen_get_speed()
|
||||||
|
with a call to rtlgen_read_status() in rtl822x_read_status().
|
||||||
|
|
||||||
|
Add reading speed to rtl822x_c45_read_status().
|
||||||
|
|
||||||
|
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
|
||||||
|
|
||||||
|
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/phy/realtek.c | 46 +++++++++++++++++++++------------------
|
||||||
|
1 file changed, 25 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/realtek.c
|
||||||
|
+++ b/drivers/net/phy/realtek.c
|
||||||
|
@@ -71,6 +71,8 @@
|
||||||
|
|
||||||
|
#define RTL822X_VND2_GANLPAR 0xa414
|
||||||
|
|
||||||
|
+#define RTL822X_VND2_PHYSR 0xa434
|
||||||
|
+
|
||||||
|
#define RTL8366RB_POWER_SAVE 0x15
|
||||||
|
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||||
|
|
||||||
|
@@ -551,17 +553,8 @@ static int rtl8366rb_config_init(struct
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get actual speed to cover the downshift case */
|
||||||
|
-static int rtlgen_get_speed(struct phy_device *phydev)
|
||||||
|
+static void rtlgen_decode_speed(struct phy_device *phydev, int val)
|
||||||
|
{
|
||||||
|
- int val;
|
||||||
|
-
|
||||||
|
- if (!phydev->link)
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- val = phy_read_paged(phydev, 0xa43, 0x12);
|
||||||
|
- if (val < 0)
|
||||||
|
- return val;
|
||||||
|
-
|
||||||
|
switch (val & RTLGEN_SPEED_MASK) {
|
||||||
|
case 0x0000:
|
||||||
|
phydev->speed = SPEED_10;
|
||||||
|
@@ -584,19 +577,26 @@ static int rtlgen_get_speed(struct phy_d
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtlgen_read_status(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
- int ret;
|
||||||
|
+ int ret, val;
|
||||||
|
|
||||||
|
ret = genphy_read_status(phydev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- return rtlgen_get_speed(phydev);
|
||||||
|
+ if (!phydev->link)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ val = phy_read_paged(phydev, 0xa43, 0x12);
|
||||||
|
+ if (val < 0)
|
||||||
|
+ return val;
|
||||||
|
+
|
||||||
|
+ rtlgen_decode_speed(phydev, val);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
|
||||||
|
@@ -817,8 +817,6 @@ static void rtl822xb_update_interface(st
|
||||||
|
|
||||||
|
static int rtl822x_read_status(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
if (phydev->autoneg == AUTONEG_ENABLE) {
|
||||||
|
int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
|
||||||
|
|
||||||
|
@@ -829,11 +827,7 @@ static int rtl822x_read_status(struct ph
|
||||||
|
lpadv);
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = genphy_read_status(phydev);
|
||||||
|
- if (ret < 0)
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
- return rtlgen_get_speed(phydev);
|
||||||
|
+ return rtlgen_read_status(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl822xb_read_status(struct phy_device *phydev)
|
||||||
|
@@ -894,6 +888,16 @@ static int rtl822x_c45_read_status(struc
|
||||||
|
mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!phydev->link)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* Read actual speed from vendor register. */
|
||||||
|
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_PHYSR);
|
||||||
|
+ if (val < 0)
|
||||||
|
+ return val;
|
||||||
|
+
|
||||||
|
+ rtlgen_decode_speed(phydev, val);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From 2d9ce64862705b33397d54dafecc5f51d8b1bb06 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eric Woudstra <ericwouds@gmail.com>
|
||||||
|
Date: Tue, 9 Apr 2024 09:30:15 +0200
|
||||||
|
Subject: [PATCH] net: phy: realtek: add rtl822x_c45_get_features() to set
|
||||||
|
supported port
|
||||||
|
|
||||||
|
Sets ETHTOOL_LINK_MODE_TP_BIT in phydev->supported.
|
||||||
|
|
||||||
|
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
|
||||||
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/phy/realtek.c | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/realtek.c
|
||||||
|
+++ b/drivers/net/phy/realtek.c
|
||||||
|
@@ -843,6 +843,14 @@ static int rtl822xb_read_status(struct p
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int rtl822x_c45_get_features(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
|
||||||
|
+ phydev->supported);
|
||||||
|
+
|
||||||
|
+ return genphy_c45_pma_read_abilities(phydev);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int rtl822x_c45_config_aneg(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
@@ -1272,6 +1280,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
+ .get_features = rtl822x_c45_get_features,
|
||||||
|
.config_aneg = rtl822x_c45_config_aneg,
|
||||||
|
.read_status = rtl822xb_c45_read_status,
|
||||||
|
.suspend = genphy_c45_pma_suspend,
|
||||||
|
@@ -1293,6 +1302,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
+ .get_features = rtl822x_c45_get_features,
|
||||||
|
.config_aneg = rtl822x_c45_config_aneg,
|
||||||
|
.read_status = rtl822xb_c45_read_status,
|
||||||
|
.suspend = genphy_c45_pma_suspend,
|
@ -1,106 +0,0 @@
|
|||||||
From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alexander Couzens <lynxis@fe80.eu>
|
|
||||||
Date: Sat, 13 Aug 2022 12:49:33 +0200
|
|
||||||
Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES
|
|
||||||
mode
|
|
||||||
|
|
||||||
The rtl8221 supports multiple SERDES modes:
|
|
||||||
- SGMII
|
|
||||||
- 2500base-x
|
|
||||||
- HiSGMII
|
|
||||||
|
|
||||||
Further it supports rate adaption on SERDES links to allow
|
|
||||||
slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII
|
|
||||||
links without reducing the SERDES speed.
|
|
||||||
|
|
||||||
When operating without rate adapters the SERDES link will follow the
|
|
||||||
ethernet speed.
|
|
||||||
|
|
||||||
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
|
||||||
---
|
|
||||||
drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++
|
|
||||||
1 file changed, 48 insertions(+)
|
|
||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
|
||||||
+++ b/drivers/net/phy/realtek.c
|
|
||||||
@@ -54,6 +54,15 @@
|
|
||||||
RTL8201F_ISR_LINK)
|
|
||||||
#define RTL8201F_IER 0x13
|
|
||||||
|
|
||||||
+#define RTL8221B_MMD_SERDES_CTRL MDIO_MMD_VEND1
|
|
||||||
+#define RTL8221B_MMD_PHY_CTRL MDIO_MMD_VEND2
|
|
||||||
+#define RTL8221B_SERDES_OPTION 0x697a
|
|
||||||
+#define RTL8221B_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
|
|
||||||
+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII 0
|
|
||||||
+#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII 1
|
|
||||||
+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
|
|
||||||
+#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
|
|
||||||
+
|
|
||||||
#define RTL8366RB_POWER_SAVE 0x15
|
|
||||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
|
||||||
|
|
||||||
@@ -879,6 +888,48 @@ static irqreturn_t rtl9000a_handle_inter
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int rtl8221b_config_init(struct phy_device *phydev)
|
|
||||||
+{
|
|
||||||
+ u16 option_mode;
|
|
||||||
+
|
|
||||||
+ switch (phydev->interface) {
|
|
||||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
|
||||||
+ if (!phydev->is_c45) {
|
|
||||||
+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ fallthrough;
|
|
||||||
+ case PHY_INTERFACE_MODE_SGMII:
|
|
||||||
+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL,
|
|
||||||
+ 0x75f3, 0);
|
|
||||||
+
|
|
||||||
+ phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL,
|
|
||||||
+ RTL8221B_SERDES_OPTION,
|
|
||||||
+ RTL8221B_SERDES_OPTION_MODE_MASK, option_mode);
|
|
||||||
+ switch (option_mode) {
|
|
||||||
+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII:
|
|
||||||
+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX:
|
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
|
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455);
|
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
|
|
||||||
+ break;
|
|
||||||
+ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII:
|
|
||||||
+ case RTL8221B_SERDES_OPTION_MODE_HISGMII:
|
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
|
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433);
|
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static struct phy_driver realtek_drvs[] = {
|
|
||||||
{
|
|
||||||
PHY_ID_MATCH_EXACT(0x00008201),
|
|
||||||
@@ -1033,6 +1084,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
PHY_ID_MATCH_EXACT(0x001cc849),
|
|
||||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY",
|
|
||||||
.get_features = rtl822x_get_features,
|
|
||||||
+ .config_init = rtl8221b_config_init,
|
|
||||||
.config_aneg = rtl822x_config_aneg,
|
|
||||||
.read_status = rtl822x_read_status,
|
|
||||||
.suspend = genphy_suspend,
|
|
||||||
@@ -1044,6 +1096,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY",
|
|
||||||
.get_features = rtl822x_get_features,
|
|
||||||
.config_aneg = rtl822x_config_aneg,
|
|
||||||
+ .config_init = rtl8221b_config_init,
|
|
||||||
.read_status = rtl822x_read_status,
|
|
||||||
.suspend = genphy_suspend,
|
|
||||||
.resume = rtlgen_resume,
|
|
@ -1,61 +0,0 @@
|
|||||||
From 312753d0aadba0f58841ae513b80fdbabc887523 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Chukun Pan <amadeus@jmu.edu.cn>
|
|
||||||
Date: Wed, 8 Feb 2023 16:32:18 +0800
|
|
||||||
Subject: [PATCH] net: phy: realtek: support switching between SGMII and
|
|
||||||
2500BASE-X for RTL822x series
|
|
||||||
|
|
||||||
After commit ace6aba ("net: phy: realtek: rtl8221: allow to configure
|
|
||||||
SERDES mode"), the rtl8221 phy can work in SGMII and 2500base-x modes
|
|
||||||
respectively. So add interface automatic switching for rtl8221 phy to
|
|
||||||
match various wire speeds.
|
|
||||||
|
|
||||||
Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
|
|
||||||
---
|
|
||||||
drivers/net/phy/realtek.c | 26 ++++++++++++++++++++++++--
|
|
||||||
1 file changed, 24 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
|
||||||
+++ b/drivers/net/phy/realtek.c
|
|
||||||
@@ -714,6 +714,25 @@ static int rtl822x_config_aneg(struct ph
|
|
||||||
return __genphy_config_aneg(phydev, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void rtl822x_update_interface(struct phy_device *phydev)
|
|
||||||
+{
|
|
||||||
+ /* Automatically switch SERDES interface between
|
|
||||||
+ * SGMII and 2500-BaseX according to speed.
|
|
||||||
+ */
|
|
||||||
+ switch (phydev->speed) {
|
|
||||||
+ case SPEED_2500:
|
|
||||||
+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
|
|
||||||
+ break;
|
|
||||||
+ case SPEED_1000:
|
|
||||||
+ case SPEED_100:
|
|
||||||
+ case SPEED_10:
|
|
||||||
+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int rtl822x_read_status(struct phy_device *phydev)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
@@ -732,11 +751,14 @@ static int rtl822x_read_status(struct ph
|
|
||||||
phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = genphy_read_status(phydev);
|
|
||||||
+ ret = rtlgen_read_status(phydev);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- return rtlgen_get_speed(phydev);
|
|
||||||
+ if (phydev->is_c45 && phydev->link)
|
|
||||||
+ rtl822x_update_interface(phydev);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
|
|
@ -15,51 +15,67 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
--- a/drivers/net/phy/realtek.c
|
||||||
+++ b/drivers/net/phy/realtek.c
|
+++ b/drivers/net/phy/realtek.c
|
||||||
@@ -1070,6 +1070,7 @@ static struct phy_driver realtek_drvs[]
|
@@ -1218,6 +1218,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
.write_page = rtl821x_write_page,
|
}, {
|
||||||
.read_mmd = rtl822x_read_mmd,
|
.name = "RTL8226 2.5Gbps PHY",
|
||||||
.write_mmd = rtl822x_write_mmd,
|
.match_phy_device = rtl8226_match_phy_device,
|
||||||
+ .soft_reset = genphy_soft_reset,
|
+ .soft_reset = genphy_soft_reset,
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.read_status = rtl822x_read_status,
|
||||||
|
@@ -1230,6 +1231,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
}, {
|
}, {
|
||||||
PHY_ID_MATCH_EXACT(0x001cc840),
|
PHY_ID_MATCH_EXACT(0x001cc840),
|
||||||
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
|
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
|
||||||
@@ -1082,6 +1083,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.write_page = rtl821x_write_page,
|
|
||||||
.read_mmd = rtl822x_read_mmd,
|
|
||||||
.write_mmd = rtl822x_write_mmd,
|
|
||||||
+ .soft_reset = genphy_soft_reset,
|
+ .soft_reset = genphy_soft_reset,
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
@@ -1244,6 +1246,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
}, {
|
}, {
|
||||||
PHY_ID_MATCH_EXACT(0x001cc838),
|
PHY_ID_MATCH_EXACT(0x001cc838),
|
||||||
.name = "RTL8226-CG 2.5Gbps PHY",
|
.name = "RTL8226-CG 2.5Gbps PHY",
|
||||||
@@ -1092,6 +1094,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.resume = rtlgen_resume,
|
|
||||||
.read_page = rtl821x_read_page,
|
|
||||||
.write_page = rtl821x_write_page,
|
|
||||||
+ .soft_reset = genphy_soft_reset,
|
+ .soft_reset = genphy_soft_reset,
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.read_status = rtl822x_read_status,
|
||||||
|
@@ -1254,6 +1257,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
}, {
|
}, {
|
||||||
PHY_ID_MATCH_EXACT(0x001cc848),
|
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||||
@@ -1102,6 +1105,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.resume = rtlgen_resume,
|
|
||||||
.read_page = rtl821x_read_page,
|
|
||||||
.write_page = rtl821x_write_page,
|
|
||||||
+ .soft_reset = genphy_soft_reset,
|
+ .soft_reset = genphy_soft_reset,
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
@@ -1266,6 +1270,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
}, {
|
}, {
|
||||||
PHY_ID_MATCH_EXACT(0x001cc849),
|
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY",
|
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||||
@@ -1113,6 +1117,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.resume = rtlgen_resume,
|
|
||||||
.read_page = rtl821x_read_page,
|
|
||||||
.write_page = rtl821x_write_page,
|
|
||||||
+ .soft_reset = genphy_soft_reset,
|
+ .soft_reset = genphy_soft_reset,
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
@@ -1278,6 +1283,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
}, {
|
}, {
|
||||||
PHY_ID_MATCH_EXACT(0x001cc84a),
|
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY",
|
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||||
@@ -1124,6 +1129,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.resume = rtlgen_resume,
|
|
||||||
.read_page = rtl821x_read_page,
|
|
||||||
.write_page = rtl821x_write_page,
|
|
||||||
+ .soft_reset = genphy_soft_reset,
|
+ .soft_reset = genphy_soft_reset,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
.get_features = rtl822x_c45_get_features,
|
||||||
|
@@ -1288,6 +1294,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
}, {
|
}, {
|
||||||
PHY_ID_MATCH_EXACT(0x001cc961),
|
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||||
.name = "RTL8366RB Gigabit Ethernet",
|
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||||
|
+ .soft_reset = genphy_soft_reset,
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
@@ -1300,6 +1307,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
}, {
|
||||||
|
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||||
|
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||||
|
+ .soft_reset = genphy_soft_reset,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
.get_features = rtl822x_c45_get_features,
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
From 2b1b8c4c215af7988136401c902338d091d408a1 Mon Sep 17 00:00:00 2001
|
From d54ef6aea00e7a6ace439baade6ad0aa38ee4b04 Mon Sep 17 00:00:00 2001
|
||||||
From: Daniel Golle <daniel@makrotopia.org>
|
From: Daniel Golle <daniel@makrotopia.org>
|
||||||
Date: Mon, 3 Apr 2023 01:21:57 +0300
|
Date: Mon, 3 Apr 2023 01:21:57 +0300
|
||||||
Subject: [PATCH 2/2] net: phy: realtek: disable SGMII in-band AN for 2.5G PHYs
|
Subject: [PATCH 287/326] net: phy: realtek: disable SGMII in-band AN for 2.5G
|
||||||
|
PHYs
|
||||||
|
|
||||||
MAC drivers don't use SGMII in-band autonegotiation unless told to do so
|
MAC drivers don't use SGMII in-band autonegotiation unless told to do so
|
||||||
in device tree using 'managed = "in-band-status"'. When using MDIO to
|
in device tree using 'managed = "in-band-status"'. When using MDIO to
|
||||||
@ -14,30 +15,49 @@ Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
|
|||||||
Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
|
Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
|
||||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
---
|
---
|
||||||
drivers/net/phy/realtek.c | 8 ++++++++
|
drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
|
||||||
1 file changed, 8 insertions(+)
|
1 file changed, 25 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
--- a/drivers/net/phy/realtek.c
|
||||||
+++ b/drivers/net/phy/realtek.c
|
+++ b/drivers/net/phy/realtek.c
|
||||||
@@ -913,6 +913,7 @@ static irqreturn_t rtl9000a_handle_inter
|
@@ -682,8 +682,8 @@ static int rtl822x_write_mmd(struct phy_
|
||||||
static int rtl8221b_config_init(struct phy_device *phydev)
|
static int rtl822xb_config_init(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
u16 option_mode;
|
bool has_2500, has_sgmii;
|
||||||
+ int val;
|
+ int ret, val;
|
||||||
|
u16 mode;
|
||||||
|
- int ret;
|
||||||
|
|
||||||
switch (phydev->interface) {
|
has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
|
||||||
case PHY_INTERFACE_MODE_2500BASEX:
|
phydev->host_interfaces) ||
|
||||||
@@ -949,6 +950,13 @@ static int rtl8221b_config_init(struct p
|
@@ -733,7 +733,29 @@ static int rtl822xb_config_init(struct p
|
||||||
break;
|
if (ret < 0)
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
+ /* Disable SGMII AN */
|
- return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7588, 0x2);
|
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7589, 0x71d0);
|
+ if (ret < 0)
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, 0x3);
|
+ return ret;
|
||||||
+ phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587,
|
|
||||||
+ val, !(val & BIT(0)), 500, 100000, false);
|
|
||||||
+
|
+
|
||||||
return 0;
|
+ /* Disable SGMII AN */
|
||||||
|
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7589, 0x71d0);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7587, 0x3);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 0x7587,
|
||||||
|
+ val, !(val & BIT(0)), 500, 100000, false);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rtl822xb_get_rate_matching(struct phy_device *phydev,
|
||||||
|
@ -18,7 +18,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
--- a/drivers/net/phy/realtek.c
|
||||||
+++ b/drivers/net/phy/realtek.c
|
+++ b/drivers/net/phy/realtek.c
|
||||||
@@ -765,9 +765,11 @@ static bool rtlgen_supports_2_5gbps(stru
|
@@ -948,9 +948,11 @@ static bool rtlgen_supports_2_5gbps(stru
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
@ -31,5 +31,5 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
+ rtl821x_write_page(phydev, 0);
|
+ rtl821x_write_page(phydev, 0);
|
||||||
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
|
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
|
||||||
|
|
||||||
return val >= 0 && val & RTL_SUPPORTS_2500FULL;
|
return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
|
||||||
}
|
}
|
||||||
|
@ -14,47 +14,13 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
--- a/drivers/net/phy/realtek.c
|
||||||
+++ b/drivers/net/phy/realtek.c
|
+++ b/drivers/net/phy/realtek.c
|
||||||
@@ -69,10 +69,6 @@
|
@@ -806,7 +806,8 @@ static int rtl822x_config_aneg(struct ph
|
||||||
#define RTL_SUPPORTS_5000FULL BIT(14)
|
|
||||||
#define RTL_SUPPORTS_2500FULL BIT(13)
|
|
||||||
#define RTL_SUPPORTS_10000FULL BIT(0)
|
|
||||||
-#define RTL_ADV_2500FULL BIT(7)
|
|
||||||
-#define RTL_LPADV_10000FULL BIT(11)
|
|
||||||
-#define RTL_LPADV_5000FULL BIT(6)
|
|
||||||
-#define RTL_LPADV_2500FULL BIT(5)
|
|
||||||
|
|
||||||
#define RTL9000A_GINMR 0x14
|
|
||||||
#define RTL9000A_GINMR_LINK_STATUS BIT(4)
|
|
||||||
@@ -699,14 +695,11 @@ static int rtl822x_config_aneg(struct ph
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (phydev->autoneg == AUTONEG_ENABLE) {
|
|
||||||
- u16 adv2500 = 0;
|
|
||||||
-
|
|
||||||
- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
|
||||||
- phydev->advertising))
|
|
||||||
- adv2500 = RTL_ADV_2500FULL;
|
|
||||||
-
|
|
||||||
ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
|
ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
|
||||||
- RTL_ADV_2500FULL, adv2500);
|
MDIO_AN_10GBT_CTRL_ADV2_5G |
|
||||||
+ MDIO_AN_10GBT_CTRL_ADV10G |
|
- MDIO_AN_10GBT_CTRL_ADV5G,
|
||||||
+ MDIO_AN_10GBT_CTRL_ADV5G |
|
+ MDIO_AN_10GBT_CTRL_ADV5G |
|
||||||
+ MDIO_AN_10GBT_CTRL_ADV2_5G,
|
+ MDIO_AN_10GBT_CTRL_ADV10G,
|
||||||
+ linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising));
|
adv);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
@@ -743,12 +736,7 @@ static int rtl822x_read_status(struct ph
|
|
||||||
if (lpadv < 0)
|
|
||||||
return lpadv;
|
|
||||||
|
|
||||||
- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
|
|
||||||
- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
|
|
||||||
- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
|
|
||||||
- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
|
|
||||||
- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
|
||||||
- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
|
|
||||||
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = rtlgen_read_status(phydev);
|
|
||||||
|
@ -15,7 +15,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
--- a/drivers/net/phy/realtek.c
|
||||||
+++ b/drivers/net/phy/realtek.c
|
+++ b/drivers/net/phy/realtek.c
|
||||||
@@ -736,6 +736,10 @@ static int rtl822x_read_status(struct ph
|
@@ -846,6 +846,10 @@ static int rtl822x_read_status(struct ph
|
||||||
if (lpadv < 0)
|
if (lpadv < 0)
|
||||||
return lpadv;
|
return lpadv;
|
||||||
|
|
||||||
@ -23,6 +23,6 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
|
+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
|
||||||
+ lpadv = 0;
|
+ lpadv = 0;
|
||||||
+
|
+
|
||||||
mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
|
mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
|
||||||
|
lpadv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
--- a/drivers/net/phy/realtek.c
|
||||||
+++ b/drivers/net/phy/realtek.c
|
+++ b/drivers/net/phy/realtek.c
|
||||||
@@ -63,6 +63,10 @@
|
@@ -73,6 +73,10 @@
|
||||||
#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
|
|
||||||
#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
|
#define RTL822X_VND2_PHYSR 0xa434
|
||||||
|
|
||||||
+#define RTL8221B_PHYCR1 0xa430
|
+#define RTL8221B_PHYCR1 0xa430
|
||||||
+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
|
+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
|
||||||
@ -24,8 +24,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
#define RTL8366RB_POWER_SAVE 0x15
|
#define RTL8366RB_POWER_SAVE 0x15
|
||||||
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
#define RTL8366RB_POWER_SAVE_ON BIT(12)
|
||||||
|
|
||||||
@@ -778,6 +782,25 @@ static int rtl8226_match_phy_device(stru
|
@@ -1003,6 +1007,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
|
||||||
rtlgen_supports_2_5gbps(phydev);
|
return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
+static int rtl822x_probe(struct phy_device *phydev)
|
+static int rtl822x_probe(struct phy_device *phydev)
|
||||||
@ -33,7 +33,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
+ struct device *dev = &phydev->mdio.dev;
|
+ struct device *dev = &phydev->mdio.dev;
|
||||||
+ int val;
|
+ int val;
|
||||||
+
|
+
|
||||||
+ val = phy_read_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1);
|
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1);
|
||||||
+ if (val < 0)
|
+ if (val < 0)
|
||||||
+ return val;
|
+ return val;
|
||||||
+
|
+
|
||||||
@ -42,7 +42,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
+ else
|
+ else
|
||||||
+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
|
+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
|
||||||
+
|
+
|
||||||
+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1, val);
|
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, val);
|
||||||
+
|
+
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
@ -50,35 +50,51 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
static int rtlgen_resume(struct phy_device *phydev)
|
static int rtlgen_resume(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
int ret = genphy_resume(phydev);
|
int ret = genphy_resume(phydev);
|
||||||
@@ -1091,6 +1114,7 @@ static struct phy_driver realtek_drvs[]
|
@@ -1275,6 +1298,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
}, {
|
||||||
|
PHY_ID_MATCH_EXACT(0x001cc838),
|
||||||
.name = "RTL8226-CG 2.5Gbps PHY",
|
.name = "RTL8226-CG 2.5Gbps PHY",
|
||||||
|
+ .probe = rtl822x_probe,
|
||||||
|
.soft_reset = genphy_soft_reset,
|
||||||
.get_features = rtl822x_get_features,
|
.get_features = rtl822x_get_features,
|
||||||
.config_aneg = rtl822x_config_aneg,
|
.config_aneg = rtl822x_config_aneg,
|
||||||
+ .probe = rtl822x_probe,
|
@@ -1286,6 +1310,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
.read_status = rtl822x_read_status,
|
}, {
|
||||||
.suspend = genphy_suspend,
|
PHY_ID_MATCH_EXACT(0x001cc848),
|
||||||
.resume = rtlgen_resume,
|
|
||||||
@@ -1102,6 +1126,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
|
||||||
|
+ .probe = rtl822x_probe,
|
||||||
|
.soft_reset = genphy_soft_reset,
|
||||||
.get_features = rtl822x_get_features,
|
.get_features = rtl822x_get_features,
|
||||||
.config_aneg = rtl822x_config_aneg,
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
@@ -1299,6 +1324,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
}, {
|
||||||
|
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||||
|
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||||
+ .probe = rtl822x_probe,
|
+ .probe = rtl822x_probe,
|
||||||
.read_status = rtl822x_read_status,
|
.soft_reset = genphy_soft_reset,
|
||||||
.suspend = genphy_suspend,
|
|
||||||
.resume = rtlgen_resume,
|
|
||||||
@@ -1114,6 +1139,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.get_features = rtl822x_get_features,
|
|
||||||
.config_init = rtl8221b_config_init,
|
|
||||||
.config_aneg = rtl822x_config_aneg,
|
|
||||||
+ .probe = rtl822x_probe,
|
|
||||||
.read_status = rtl822x_read_status,
|
|
||||||
.suspend = genphy_suspend,
|
|
||||||
.resume = rtlgen_resume,
|
|
||||||
@@ -1126,6 +1152,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.get_features = rtl822x_get_features,
|
.get_features = rtl822x_get_features,
|
||||||
.config_aneg = rtl822x_config_aneg,
|
.config_aneg = rtl822x_config_aneg,
|
||||||
.config_init = rtl8221b_config_init,
|
@@ -1312,6 +1338,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
}, {
|
||||||
|
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||||
|
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||||
+ .probe = rtl822x_probe,
|
+ .probe = rtl822x_probe,
|
||||||
.read_status = rtl822x_read_status,
|
.soft_reset = genphy_soft_reset,
|
||||||
.suspend = genphy_suspend,
|
.config_init = rtl822xb_config_init,
|
||||||
.resume = rtlgen_resume,
|
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
@@ -1323,6 +1350,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
}, {
|
||||||
|
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||||
|
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||||
|
+ .probe = rtl822x_probe,
|
||||||
|
.soft_reset = genphy_soft_reset,
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
.config_aneg = rtl822x_config_aneg,
|
||||||
|
@@ -1336,6 +1364,7 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
}, {
|
||||||
|
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||||
|
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||||
|
+ .probe = rtl822x_probe,
|
||||||
|
.soft_reset = genphy_soft_reset,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
Date: Sun, 30 Apr 2023 00:15:41 +0100
|
|
||||||
Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
|
|
||||||
|
|
||||||
Early versions (?) of the RTL8221B PHY cannot be identified in a regular
|
|
||||||
Clause-45 bus scan as the PHY doesn't report the implemented MMDs
|
|
||||||
correctly but returns 0 instead.
|
|
||||||
Implement custom identify function using the PKGID instead of iterating
|
|
||||||
over the implemented MMDs.
|
|
||||||
|
|
||||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
|
||||||
+++ b/drivers/net/phy/realtek.c
|
|
||||||
@@ -81,6 +81,7 @@
|
|
||||||
|
|
||||||
#define RTL_GENERIC_PHYID 0x001cc800
|
|
||||||
#define RTL_8211FVD_PHYID 0x001cc878
|
|
||||||
+#define RTL_8221B_VB_CG_PHYID 0x001cc849
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("Realtek PHY driver");
|
|
||||||
MODULE_AUTHOR("Johnson Leung");
|
|
||||||
@@ -782,6 +783,38 @@ static int rtl8226_match_phy_device(stru
|
|
||||||
rtlgen_supports_2_5gbps(phydev);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev)
|
|
||||||
+{
|
|
||||||
+ int val;
|
|
||||||
+ u32 id;
|
|
||||||
+
|
|
||||||
+ if (phydev->mdio.bus->read_c45) {
|
|
||||||
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
|
|
||||||
+ if (val < 0)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ id = val << 16;
|
|
||||||
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
|
|
||||||
+ if (val < 0)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ id |= val;
|
|
||||||
+ } else {
|
|
||||||
+ val = phy_read(phydev, MII_PHYSID1);
|
|
||||||
+ if (val < 0)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ id = val << 16;
|
|
||||||
+ val = phy_read(phydev, MII_PHYSID2);
|
|
||||||
+ if (val < 0)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ id |= val;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return (id == RTL_8221B_VB_CG_PHYID);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int rtl822x_probe(struct phy_device *phydev)
|
|
||||||
{
|
|
||||||
struct device *dev = &phydev->mdio.dev;
|
|
||||||
@@ -1134,7 +1167,7 @@ static struct phy_driver realtek_drvs[]
|
|
||||||
.write_page = rtl821x_write_page,
|
|
||||||
.soft_reset = genphy_soft_reset,
|
|
||||||
}, {
|
|
||||||
- PHY_ID_MATCH_EXACT(0x001cc849),
|
|
||||||
+ .match_phy_device = rtl8221b_vb_cg_match_phy_device,
|
|
||||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY",
|
|
||||||
.get_features = rtl822x_get_features,
|
|
||||||
.config_init = rtl8221b_config_init,
|
|
@ -12,15 +12,15 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
|||||||
|
|
||||||
--- a/drivers/net/phy/realtek.c
|
--- a/drivers/net/phy/realtek.c
|
||||||
+++ b/drivers/net/phy/realtek.c
|
+++ b/drivers/net/phy/realtek.c
|
||||||
@@ -1010,6 +1010,51 @@ static int rtl8221b_config_init(struct p
|
@@ -1161,6 +1161,51 @@ static irqreturn_t rtl9000a_handle_inter
|
||||||
return 0;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
+static int rtl8221b_ack_interrupt(struct phy_device *phydev)
|
+static int rtl8221b_ack_interrupt(struct phy_device *phydev)
|
||||||
+{
|
+{
|
||||||
+ int err;
|
+ int err;
|
||||||
+
|
+
|
||||||
+ err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4);
|
+ err = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa4d4);
|
||||||
+
|
+
|
||||||
+ return (err < 0) ? err : 0;
|
+ return (err < 0) ? err : 0;
|
||||||
+}
|
+}
|
||||||
@ -34,9 +34,9 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
|||||||
+ if (err)
|
+ if (err)
|
||||||
+ return err;
|
+ return err;
|
||||||
+
|
+
|
||||||
+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff);
|
+ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x7ff);
|
||||||
+ } else {
|
+ } else {
|
||||||
+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0);
|
+ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x0);
|
||||||
+ if (err)
|
+ if (err)
|
||||||
+ return err;
|
+ return err;
|
||||||
+
|
+
|
||||||
@ -64,12 +64,39 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
|||||||
static struct phy_driver realtek_drvs[] = {
|
static struct phy_driver realtek_drvs[] = {
|
||||||
{
|
{
|
||||||
PHY_ID_MATCH_EXACT(0x00008201),
|
PHY_ID_MATCH_EXACT(0x00008201),
|
||||||
@@ -1172,6 +1217,8 @@ static struct phy_driver realtek_drvs[]
|
@@ -1324,6 +1369,8 @@ static struct phy_driver realtek_drvs[]
|
||||||
.get_features = rtl822x_get_features,
|
}, {
|
||||||
.config_init = rtl8221b_config_init,
|
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||||
.config_aneg = rtl822x_config_aneg,
|
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||||
+ .config_intr = rtl8221b_config_intr,
|
+ .config_intr = rtl8221b_config_intr,
|
||||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||||
.probe = rtl822x_probe,
|
.probe = rtl822x_probe,
|
||||||
.read_status = rtl822x_read_status,
|
.soft_reset = genphy_soft_reset,
|
||||||
.suspend = genphy_suspend,
|
.get_features = rtl822x_get_features,
|
||||||
|
@@ -1338,6 +1385,8 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
}, {
|
||||||
|
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||||
|
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||||
|
+ .config_intr = rtl8221b_config_intr,
|
||||||
|
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||||
|
.probe = rtl822x_probe,
|
||||||
|
.soft_reset = genphy_soft_reset,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
@@ -1350,6 +1399,8 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
}, {
|
||||||
|
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||||
|
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||||
|
+ .config_intr = rtl8221b_config_intr,
|
||||||
|
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||||
|
.probe = rtl822x_probe,
|
||||||
|
.soft_reset = genphy_soft_reset,
|
||||||
|
.get_features = rtl822x_get_features,
|
||||||
|
@@ -1364,6 +1415,8 @@ static struct phy_driver realtek_drvs[]
|
||||||
|
}, {
|
||||||
|
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||||
|
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||||
|
+ .config_intr = rtl8221b_config_intr,
|
||||||
|
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||||
|
.probe = rtl822x_probe,
|
||||||
|
.soft_reset = genphy_soft_reset,
|
||||||
|
.config_init = rtl822xb_config_init,
|
||||||
|
Loading…
Reference in New Issue
Block a user