diff options
| author | Markus Stockhausen | 2025-06-03 18:21:48 +0000 |
|---|---|---|
| committer | Robert Marko | 2025-06-11 20:27:22 +0000 |
| commit | ec310a0993e74d64ebf9bd2b649a3ac321e3bf82 (patch) | |
| tree | 55eeeb6681844e604221a628be7123c64541a088 | |
| parent | 30fae30e038ba6a5fe8184fa339355cfcfd15c43 (diff) | |
| download | openwrt-ec310a0993e74d64ebf9bd2b649a3ac321e3bf82.tar.gz | |
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@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
| -rw-r--r-- | target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c | 39 |
1 files 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) |