Skip to content

Commit ec310a0

Browse files
plappermaulrobimarko
authored andcommitted
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 <[email protected]> Link: openwrt#18935 Signed-off-by: Robert Marko <[email protected]>
1 parent 30fae30 commit ec310a0

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -981,21 +981,40 @@ static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
981981
return 0;
982982
}
983983

984-
static bool rtl8214fc_media_is_fibre(struct phy_device *phydev)
984+
static bool __rtl8214fc_media_is_fibre(struct phy_device *phydev)
985985
{
986-
int mac = phydev->mdio.addr;
986+
struct mii_bus *bus = phydev->mdio.bus;
987+
static int regs[] = {16, 19, 20, 21};
988+
int addr = phydev->mdio.addr & ~3;
989+
int reg = regs[phydev->mdio.addr & 3];
990+
int oldpage, val;
987991

988-
static int reg[] = {16, 19, 20, 21};
989-
u32 val;
992+
/*
993+
* The fiber status cannot be read directly from the phy. It is a package "global"
994+
* attribute and therefore located in the first phy. To avoid state handling assume
995+
* an aligment to addresses divisible by 4.
996+
*/
990997

991-
phy_package_write_paged(phydev, RTL838X_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
992-
val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]);
993-
phy_package_write_paged(phydev, RTL838X_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
998+
oldpage = __mdiobus_read(bus, addr, RTL8XXX_PAGE_SELECT);
999+
__mdiobus_write(bus, addr, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
1000+
__mdiobus_write(bus, addr, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PORT);
1001+
val = __mdiobus_read(bus, addr, reg);
1002+
__mdiobus_write(bus, addr, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
1003+
__mdiobus_write(bus, addr, RTL8XXX_PAGE_SELECT, oldpage);
9941004

995-
if (val & BMCR_PDOWN)
996-
return false;
1005+
return !(val & BMCR_PDOWN);
1006+
}
1007+
1008+
static bool rtl8214fc_media_is_fibre(struct phy_device *phydev)
1009+
{
1010+
struct mii_bus *bus = phydev->mdio.bus;
1011+
int ret;
9971012

998-
return true;
1013+
mutex_lock(&bus->mdio_lock);
1014+
ret = __rtl8214fc_media_is_fibre(phydev);
1015+
mutex_unlock(&bus->mdio_lock);
1016+
1017+
return ret;
9991018
}
10001019

10011020
static void rtl8214fc_power_set(struct phy_device *phydev, int port, bool on)

0 commit comments

Comments
 (0)