From: Eric Woudstra <ericwouds@gmail.com>
To: "Andrew Lunn" <andrew@lunn.ch>,
"Heiner Kallweit" <hkallweit1@gmail.com>,
"Russell King" <linux@armlinux.org.uk>,
"David S. Miller" <davem@davemloft.net>,
"Eric Dumazet" <edumazet@google.com>,
"Jakub Kicinski" <kuba@kernel.org>,
"Paolo Abeni" <pabeni@redhat.com>,
"Marek Behún" <kabel@kernel.org>,
"Frank Wunderlich" <frank-w@public-files.de>,
"Daniel Golle" <daniel@makrotopia.org>
Cc: netdev@vger.kernel.org, Eric Woudstra <ericwouds@gmail.com>
Subject: [PATCH RFC net-next 4/6] net: phy: realtek: Add driver instances for rtl8221b/8251b via Clause 45
Date: Tue, 27 Feb 2024 08:51:49 +0100 [thread overview]
Message-ID: <20240227075151.793496-5-ericwouds@gmail.com> (raw)
In-Reply-To: <20240227075151.793496-1-ericwouds@gmail.com>
Add driver instances for Clause 45 communication with the RTL8221B/8251B.
This is used by Clause 45 only accessible PHY's on several sfp modules,
which are using RollBall protocol.
Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
---
drivers/net/phy/realtek.c | 171 ++++++++++++++++++++++++++++++++++++--
1 file changed, 165 insertions(+), 6 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index e7c42ec18971..e7964ce158c3 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -64,6 +64,15 @@
#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 RTL822X_VND2_PHYSR 0xa434
+
#define RTL8366RB_POWER_SAVE 0x15
#define RTL8366RB_POWER_SAVE_ON BIT(12)
@@ -74,6 +83,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");
@@ -821,6 +833,76 @@ static int rtl822x_read_status(struct phy_device *phydev)
return 0;
}
+static int rtl822x_c45_get_features(struct phy_device *phydev)
+{
+ linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
+ phydev->supported);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT,
+ phydev->supported);
+
+ return genphy_c45_pma_read_abilities(phydev);
+}
+
+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);
+ }
+
+ 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_get_speed(phydev, val);
+
+ rtl822x_update_interface(phydev);
+
+ return 0;
+}
+
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
{
int val;
@@ -844,6 +926,44 @@ static int rtl8226_match_phy_device(struct phy_device *phydev)
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 rtl8251b_c22_match_phy_device(struct phy_device *phydev)
+{
+ return rtlgen_is_c45_match(phydev, RTL_8251B, false);
+}
+
+static int rtl8251b_c45_match_phy_device(struct phy_device *phydev)
+{
+ return rtlgen_is_c45_match(phydev, RTL_8251B, true);
+}
+
static int rtlgen_resume(struct phy_device *phydev)
{
int ret = genphy_resume(phydev);
@@ -854,6 +974,15 @@ static int rtlgen_resume(struct phy_device *phydev)
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;
@@ -1129,8 +1258,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_init = rtl822x_config_init,
.get_rate_matching = rtl822x_get_rate_matching,
@@ -1141,8 +1270,18 @@ 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 = rtl822x_config_init,
+ .get_rate_matching = rtl822x_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
+ .config_aneg = rtl822x_c45_config_aneg,
+ .read_status = rtl822x_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 = rtl822x_config_init,
@@ -1153,8 +1292,18 @@ 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",
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
+ .config_init = rtl822x_config_init,
+ .get_rate_matching = rtl822x_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
+ .config_aneg = rtl822x_c45_config_aneg,
+ .read_status = rtl822x_c45_read_status,
+ .suspend = genphy_c45_pma_suspend,
+ .resume = rtlgen_c45_resume,
+ }, {
+ .match_phy_device = rtl8251b_c22_match_phy_device,
+ .name = "RTL8251B 5Gbps PHY (C22)",
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
.config_init = rtl822x_config_init,
@@ -1164,6 +1313,16 @@ static struct phy_driver realtek_drvs[] = {
.resume = rtlgen_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
+ }, {
+ .match_phy_device = rtl8251b_c45_match_phy_device,
+ .name = "RTL8251B 5Gbps PHY (C45)",
+ .config_init = rtl822x_config_init,
+ .get_rate_matching = rtl822x_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
+ .config_aneg = rtl822x_c45_config_aneg,
+ .read_status = rtl822x_c45_read_status,
+ .suspend = genphy_c45_pma_suspend,
+ .resume = rtlgen_c45_resume,
}, {
PHY_ID_MATCH_EXACT(0x001cc961),
.name = "RTL8366RB Gigabit Ethernet",
--
2.42.1
next prev parent reply other threads:[~2024-02-27 7:52 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-27 7:51 [PATCH RFC net-next 0/6] rtl8221b/8251b add C45 instances and SerDes switching Eric Woudstra
2024-02-27 7:51 ` [PATCH RFC net-next 1/6] net: phy: realtek: configure SerDes mode for rtl822x/8251b PHYs Eric Woudstra
2024-02-27 10:36 ` Russell King (Oracle)
2024-02-27 13:34 ` Eric Woudstra
2024-02-29 12:50 ` Marek Behún
2024-02-29 16:34 ` Daniel Golle
2024-03-01 9:24 ` Marek Behún
2024-02-27 7:51 ` [PATCH RFC net-next 2/6] net: phy: realtek: add get_rate_matching() " Eric Woudstra
2024-02-27 10:37 ` Russell King (Oracle)
2024-02-27 7:51 ` [PATCH RFC net-next 3/6] net: phy: realtek: rtlgen_get_speed(): Pass register value as argument Eric Woudstra
2024-02-27 10:38 ` Russell King (Oracle)
2024-02-27 7:51 ` Eric Woudstra [this message]
2024-02-27 10:41 ` [PATCH RFC net-next 4/6] net: phy: realtek: Add driver instances for rtl8221b/8251b via Clause 45 Russell King (Oracle)
2024-03-01 9:29 ` Marek Behún
2024-02-27 7:51 ` [PATCH RFC net-next 5/6] net: phy: sfp: Fixup for OEM SFP-2.5G-T module Eric Woudstra
2024-02-27 10:42 ` Russell King (Oracle)
2024-02-27 7:51 ` [PATCH RFC net-next 6/6] net: sfp: add quirk for another multigig RollBall transceiver Eric Woudstra
2024-02-27 10:42 ` Russell King (Oracle)
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=20240227075151.793496-5-ericwouds@gmail.com \
--to=ericwouds@gmail.com \
--cc=andrew@lunn.ch \
--cc=daniel@makrotopia.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=frank-w@public-files.de \
--cc=hkallweit1@gmail.com \
--cc=kabel@kernel.org \
--cc=kuba@kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.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.