[openwrt/openwrt] realtek: 6.12: allow fiber media status to be read without lock

LEDE Commits lede-commits at lists.infradead.org
Wed Jun 11 13:27:53 PDT 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/ec310a0993e74d64ebf9bd2b649a3ac321e3bf82

commit ec310a0993e74d64ebf9bd2b649a3ac321e3bf82
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Tue Jun 3 14:21:48 2025 -0400

    realtek: 6.12: allow fiber media status to be read without lock
    
    rtl8214fc_media_is_fibre() will need to be run when bus lock is held.
    Split the function into two versions.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/18935
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../files-6.12/drivers/net/phy/rtl83xx-phy.c       | 39 ++++++++++++++++------
 1 file changed, 29 insertions(+), 10 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 ab8126f82a..8d30348082 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
@@ -981,21 +981,40 @@ static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
 	return 0;
 }
 
-static bool rtl8214fc_media_is_fibre(struct phy_device *phydev)
+static bool __rtl8214fc_media_is_fibre(struct phy_device *phydev)
 {
-	int mac = phydev->mdio.addr;
+	struct mii_bus *bus = phydev->mdio.bus;
+	static int regs[] = {16, 19, 20, 21};
+	int addr = phydev->mdio.addr & ~3;
+	int reg = regs[phydev->mdio.addr & 3];
+	int oldpage, val;
 
-	static int reg[] = {16, 19, 20, 21};
-	u32 val;
+	/*
+	 * The fiber status cannot be read directly from the phy. It is a package "global"
+	 * attribute and therefore located in the first phy. To avoid state handling assume
+	 * an aligment to addresses divisible by 4.
+	 */
 
-	phy_package_write_paged(phydev, RTL838X_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
-	val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]);
-	phy_package_write_paged(phydev, RTL838X_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+	oldpage = __mdiobus_read(bus, addr, RTL8XXX_PAGE_SELECT);
+	__mdiobus_write(bus, addr, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+	__mdiobus_write(bus, addr, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PORT);
+	val = __mdiobus_read(bus, addr, reg);
+	__mdiobus_write(bus, addr, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+	__mdiobus_write(bus, addr, RTL8XXX_PAGE_SELECT, oldpage);
 
-	if (val & BMCR_PDOWN)
-		return false;
+	return !(val & BMCR_PDOWN);
+}
+
+static bool rtl8214fc_media_is_fibre(struct phy_device *phydev)
+{
+	struct mii_bus *bus = phydev->mdio.bus;
+	int ret;
 
-	return true;
+	mutex_lock(&bus->mdio_lock);
+	ret = __rtl8214fc_media_is_fibre(phydev);
+	mutex_unlock(&bus->mdio_lock);
+
+	return ret;
 }
 
 static void rtl8214fc_power_set(struct phy_device *phydev, int port, bool on)




More information about the lede-commits mailing list