From: "Marek Behún" <kabel@kernel.org>
To: netdev@vger.kernel.org, Andrew Lunn <andrew@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: "Russell King" <rmk+kernel@armlinux.org.uk>,
"Alexander Couzens" <lynxis@fe80.eu>,
"Daniel Golle" <daniel@makrotopia.org>,
"Heiner Kallweit" <hkallweit1@gmail.com>,
"Willy Liu" <willy.liu@realtek.com>,
"Ioana Ciornei" <ioana.ciornei@nxp.com>,
"Marek Mojík" <marek.mojik@nic.cz>,
"Maximilián Maliar" <maximilian.maliar@nic.cz>,
"Marek Behún" <kabel@kernel.org>
Subject: [PATCH net-next 14/15] net: phy: realtek: configure SerDes mode for rtl822x PHYs
Date: Wed, 20 Dec 2023 16:55:17 +0100 [thread overview]
Message-ID: <20231220155518.15692-15-kabel@kernel.org> (raw)
In-Reply-To: <20231220155518.15692-1-kabel@kernel.org>
From: Alexander Couzens <lynxis@fe80.eu>
The rtl822x 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.
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>
---
drivers/net/phy/realtek.c | 97 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index e2f68ac4b005..5d03c5b7afb5 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -54,6 +54,11 @@
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 RTL8221_GBCR 0xa412
#define RTL8221_GANLPAR 0xa414
@@ -663,6 +668,60 @@ static int rtl822x_resume(struct phy_device *phydev)
return 0;
}
+static int rtl822x_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;
+
+ if (!has_2500 && !has_sgmii)
+ return 0;
+
+ /* 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);
+
+ /* determine SerDes option mode */
+ if (has_2500 && !has_sgmii)
+ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX;
+ else
+ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII;
+
+ 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;
+
+ /* the following 3 writes into SerDes control are needed for 2500base-x
+ * mode to work properly
+ */
+ 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_config_aneg(struct phy_device *phydev)
{
bool changed = false;
@@ -689,9 +748,31 @@ static int rtl822x_config_aneg(struct phy_device *phydev)
return genphy_c45_check_and_restart_aneg(phydev, changed);
}
+static void rtl822x_update_interface(struct phy_device *phydev)
+{
+ /* PHY changes SerDes mode between 2500base-x and sgmii based on
+ * copper speed, if sgmii is supported
+ */
+ if (!test_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces))
+ return;
+
+ 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 val;
+ int ret, val;
if (phydev->autoneg == AUTONEG_ENABLE) {
val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL8221_GANLPAR);
@@ -701,7 +782,13 @@ static int rtl822x_read_status(struct phy_device *phydev)
mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
}
- return genphy_c45_read_status(phydev);
+ ret = genphy_c45_read_status(phydev);
+ if (ret < 0)
+ return ret;
+
+ rtl822x_update_interface(phydev);
+
+ return 0;
}
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
@@ -959,6 +1046,7 @@ static struct phy_driver realtek_drvs[] = {
.name = "RTL8226 2.5Gbps PHY",
.match_phy_device = rtl8226_match_phy_device,
.probe = rtl822x_probe,
+ .config_init = rtl822x_config_init,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.suspend = genphy_c45_pma_suspend,
@@ -969,6 +1057,7 @@ static struct phy_driver realtek_drvs[] = {
PHY_ID_MATCH_EXACT(0x001cc840),
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
.probe = rtl822x_probe,
+ .config_init = rtl822x_config_init,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.suspend = genphy_c45_pma_suspend,
@@ -979,6 +1068,7 @@ static struct phy_driver realtek_drvs[] = {
PHY_ID_MATCH_EXACT(0x001cc838),
.name = "RTL8226-CG 2.5Gbps PHY",
.probe = rtl822x_probe,
+ .config_init = rtl822x_config_init,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.suspend = genphy_c45_pma_suspend,
@@ -989,6 +1079,7 @@ static struct phy_driver realtek_drvs[] = {
PHY_ID_MATCH_EXACT(0x001cc848),
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
.probe = rtl822x_probe,
+ .config_init = rtl822x_config_init,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.suspend = genphy_c45_pma_suspend,
@@ -999,6 +1090,7 @@ static struct phy_driver realtek_drvs[] = {
PHY_ID_MATCH_EXACT(0x001cc849),
.name = "RTL8221B-VB-CG 2.5Gbps PHY",
.probe = rtl822x_probe,
+ .config_init = rtl822x_config_init,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.suspend = genphy_c45_pma_suspend,
@@ -1009,6 +1101,7 @@ static struct phy_driver realtek_drvs[] = {
PHY_ID_MATCH_EXACT(0x001cc84a),
.name = "RTL8221B-VM-CG 2.5Gbps PHY",
.probe = rtl822x_probe,
+ .config_init = rtl822x_config_init,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.suspend = genphy_c45_pma_suspend,
--
2.41.0
next prev parent reply other threads:[~2023-12-20 15:56 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-20 15:55 [PATCH net-next 00/15] Realtek RTL822x PHY rework to c45 and SerDes interface switching Marek Behún
2023-12-20 15:55 ` [PATCH net-next 01/15] net: phy: fail early with error code if indirect MMD access fails Marek Behún
2024-01-02 11:09 ` Russell King (Oracle)
2023-12-20 15:55 ` [PATCH net-next 02/15] net: phy: export indirect MMD register accessors Marek Behún
2024-01-02 11:15 ` Russell King (Oracle)
2023-12-20 15:55 ` [PATCH net-next 03/15] net: phy: realtek: rework MMD register access methods Marek Behún
2024-01-02 11:16 ` Russell King (Oracle)
2024-01-02 13:18 ` Heiner Kallweit
2023-12-20 15:55 ` [PATCH net-next 04/15] net: phy: realtek: fill .read_mmd and .write_mmd methods for all rtl822x PHYs Marek Behún
2024-01-02 11:16 ` Russell King (Oracle)
2023-12-20 15:55 ` [PATCH net-next 05/15] net: mdio: add 2.5g and 5g related PMA speed constants Marek Behún
2024-01-02 11:05 ` Russell King (Oracle)
2023-12-20 15:55 ` [PATCH net-next 06/15] net: phy: realtek: use generic MDIO constants Marek Behún
2024-01-02 11:06 ` Russell King (Oracle)
2023-12-20 15:55 ` [PATCH net-next 07/15] net: phy: realtek: set is_c45 and fill in c45 IDs in PHY probe for rtl822x PHYs Marek Behún
2023-12-20 15:55 ` [PATCH net-next 08/15] net: phy: realtek: use generic clause 45 feature reading " Marek Behún
2023-12-20 15:55 ` [PATCH net-next 09/15] net: phy: realtek: read standard MMD register for rtlgen speed capability Marek Behún
2023-12-20 15:55 ` [PATCH net-next 10/15] net: phy: realtek: use generic c45 AN config with 1000baseT vendor extension for rtl822x Marek Behún
2023-12-20 15:55 ` [PATCH net-next 11/15] net: phy: realtek: use generic c45 status reading " Marek Behún
2023-12-20 15:55 ` [PATCH net-next 12/15] net: phy: realtek: use generic c45 suspend/resume " Marek Behún
2023-12-20 15:55 ` [PATCH net-next 13/15] net: phy: realtek: drop .read_page and .write_page for rtl822x series Marek Behún
2023-12-20 17:23 ` Heiner Kallweit
2023-12-21 10:21 ` Marek Behún
2023-12-20 15:55 ` Marek Behún [this message]
2023-12-20 15:55 ` [PATCH net-next 15/15] net: sfp: add quirk for another multigig RollBall transceiver Marek Behún
2023-12-20 16:20 ` [PATCH net-next 00/15] Realtek RTL822x PHY rework to c45 and SerDes interface switching Heiner Kallweit
2023-12-20 16:25 ` Marek Behún
2023-12-20 17:07 ` Heiner Kallweit
2023-12-23 19:09 ` Heiner Kallweit
2023-12-25 10:28 ` Marek Behún
2023-12-26 12:46 ` Heiner Kallweit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231220155518.15692-15-kabel@kernel.org \
--to=kabel@kernel.org \
--cc=andrew@lunn.ch \
--cc=daniel@makrotopia.org \
--cc=davem@davemloft.net \
--cc=hkallweit1@gmail.com \
--cc=ioana.ciornei@nxp.com \
--cc=kuba@kernel.org \
--cc=lynxis@fe80.eu \
--cc=marek.mojik@nic.cz \
--cc=maximilian.maliar@nic.cz \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rmk+kernel@armlinux.org.uk \
--cc=willy.liu@realtek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.