mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2025-12-09 14:12:10 -05:00
The addition of the soft_reset() function to the RTL8221B PHYs
missed to take care of C22/C45 standalone PHY versions. Especially
on RTL930x switch devices with these PHY the reset fails for the
C45 operation mode. This comes from the fact that the mdio bus
disables C22 read/writes when being set to C45.
Upstream has gained a proper C45 reset function. Use it for the
C45 PHY models.
Fixes: 7e3284eef7 ("generic: use genphy_soft_reset for RealTek 2.5G PHYs")
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19843
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
103 lines
3.1 KiB
Diff
103 lines
3.1 KiB
Diff
From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
|
|
From: Jianhui Zhao <zhaojh329@gmail.com>
|
|
Date: Sun, 24 Sep 2023 22:15:00 +0800
|
|
Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
|
|
|
|
This commit introduces interrupt support for RTL8221B.
|
|
|
|
Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
|
---
|
|
drivers/net/phy/realtek/realtek_main.c | 47 +++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 47 insertions(+)
|
|
|
|
--- a/drivers/net/phy/realtek/realtek_main.c
|
|
+++ b/drivers/net/phy/realtek/realtek_main.c
|
|
@@ -1610,6 +1610,51 @@ static irqreturn_t rtl9000a_handle_inter
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
+static int rtl8221b_ack_interrupt(struct phy_device *phydev)
|
|
+{
|
|
+ int err;
|
|
+
|
|
+ err = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa4d4);
|
|
+
|
|
+ return (err < 0) ? err : 0;
|
|
+}
|
|
+
|
|
+static int rtl8221b_config_intr(struct phy_device *phydev)
|
|
+{
|
|
+ int err;
|
|
+
|
|
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
|
|
+ err = rtl8221b_ack_interrupt(phydev);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x7ff);
|
|
+ } else {
|
|
+ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x0);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ err = rtl8221b_ack_interrupt(phydev);
|
|
+ }
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
|
|
+{
|
|
+ int err;
|
|
+
|
|
+ err = rtl8221b_ack_interrupt(phydev);
|
|
+ if (err) {
|
|
+ phy_error(phydev);
|
|
+ return IRQ_NONE;
|
|
+ }
|
|
+
|
|
+ phy_trigger_machine(phydev);
|
|
+
|
|
+ return IRQ_HANDLED;
|
|
+}
|
|
+
|
|
static struct phy_driver realtek_drvs[] = {
|
|
{
|
|
PHY_ID_MATCH_EXACT(0x00008201),
|
|
@@ -1774,6 +1819,8 @@ static struct phy_driver realtek_drvs[]
|
|
}, {
|
|
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
|
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
|
+ .config_intr = rtl8221b_config_intr,
|
|
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
|
.soft_reset = genphy_soft_reset,
|
|
.probe = rtl822x_probe,
|
|
.get_features = rtl822x_get_features,
|
|
@@ -1788,6 +1835,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,
|
|
.soft_reset = rtl822x_c45_soft_reset,
|
|
.probe = rtl822x_probe,
|
|
.config_init = rtl822xb_config_init,
|
|
@@ -1800,6 +1849,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,
|
|
.soft_reset = genphy_soft_reset,
|
|
.probe = rtl822x_probe,
|
|
.get_features = rtl822x_get_features,
|
|
@@ -1814,6 +1865,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,
|
|
.soft_reset = rtl822x_c45_soft_reset,
|
|
.probe = rtl822x_probe,
|
|
.config_init = rtl822xb_config_init,
|