summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Stockhausen2026-01-18 21:09:00 +0000
committerRobert Marko2026-01-24 10:44:10 +0000
commit372f2563f602363c0b68d5263039c5649490a175 (patch)
tree1f5954b86d9336a2035481cfac6f674c7dbd0479
parent45fb8f9739272fc6d12ee4bc44cae5c217341a10 (diff)
downloadopenwrt-372f2563f602363c0b68d5263039c5649490a175.tar.gz
realtek: phy: fix RTL8214FC fibre/copper initialization
A phy is configured in two stages - phy_probe() for setup of structures - config_init() for device setup (after reset) RTL8214FC is a combo phy and the currently active port can be switched with the SFP helper functions that are triggered during SFP insertion and removal. In case a fibre SFP is inserted while booting the SFP trigger is run between the above mentioned stages. During the final setup in config_init() the phy is reset to the copper port. Thus no link is available on fibre and the SFP must be reinserted for normal operation. For a consistent behaviour the fibre/copper port setup must run before the SFP probing and not afterwards. Move the setup code from config_init() into phy_probe(). Fixes: 10ae743 ("realtek: phy: simplify RTL8214FC configuration") Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de> Link: https://github.com/openwrt/openwrt/pull/21582 Signed-off-by: Robert Marko <robimarko@gmail.com>
-rw-r--r--target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
index b47e88aa98..4eb4d138a1 100644
--- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
+++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c
@@ -863,45 +863,45 @@ static int rtl8218b_config_init(struct phy_device *phydev)
return 0;
}
-static int rtl8214fc_config_init(struct phy_device *phydev)
+static int rtl8214fc_phy_probe(struct phy_device *phydev)
{
static int regs[] = {16, 19, 20, 21};
int ret;
+ rtl821x_package_join(phydev, 4);
+
+ /*
+ * Normally phy_probe() only initializes PHY structures and setup is run in
+ * config_init(). The RTL8214FC needs configuration before SFP probing while
+ * the preferred media is still copper. This way all SFP events (even before
+ * the first config_init()) will find a consistent port state.
+ */
+
/* Step 1 - package setup: Due to similar design reuse RTL8218B coding */
ret = rtl8218b_config_init(phydev);
if (ret)
return ret;
if (phydev->mdio.addr % 8 == 0) {
- for (int port = 0; port < 4; port++) {
- phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, 0x8);
- /* setup basic fiber control in base phy and default to copper */
- phy_write_paged(phydev, 0x266, regs[port], 0x0f95);
- phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, 0x0);
- }
+ /* Force all ports to copper */
+ phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+ for (int port = 0; port < 4; port++)
+ phy_modify_paged(phydev, 0x266, regs[port], 0, GENMASK(11, 10));
}
/* Step 2 - port setup */
- phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, 0x3);
+ phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE);
/* set fiber SerDes RX to negative edge */
phy_modify_paged(phydev, 0x8, 0x17, 0, BIT(14));
/* auto negotiation disable link on */
phy_modify_paged(phydev, 0x8, 0x14, 0, BIT(2));
/* disable fiber 100MBit */
phy_modify_paged(phydev, 0x8, 0x11, BIT(5), 0);
- phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, 0x0);
+ phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
/* Disable EEE. 0xa5d/0x10 is the same as MDIO_MMD_AN / MDIO_AN_EEE_ADV */
phy_write_paged(phydev, 0xa5d, 0x10, 0x0000);
- return 0;
-}
-
-static int rtl8214fc_phy_probe(struct phy_device *phydev)
-{
- rtl821x_package_join(phydev, 4);
-
return phy_sfp_probe(phydev, &rtl8214fc_sfp_ops);
}
@@ -920,7 +920,6 @@ static struct phy_driver rtl83xx_phy_driver[] = {
.match_phy_device = rtl8214fc_match_phy_device,
.name = "Realtek RTL8214FC",
.config_aneg = rtl8214fc_config_aneg,
- .config_init = rtl8214fc_config_init,
.get_features = rtl8214fc_get_features,
.get_tunable = rtl8214fc_get_tunable,
.probe = rtl8214fc_phy_probe,