--- zzzz-none-000/linux-4.9.231/drivers/net/phy/phy.c 2020-07-22 07:10:54.000000000 +0000 +++ falcon-5590-729/linux-4.9.231/drivers/net/phy/phy.c 2022-03-30 12:03:34.000000000 +0000 @@ -473,6 +473,53 @@ } EXPORT_SYMBOL(phy_ethtool_ksettings_get); +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr) +{ + u32 cmd; + int tmp; + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + struct ethtool_value edata = { ETHTOOL_GLINK }; + + if (get_user(cmd, (u32 *)useraddr)) + return -EFAULT; + + switch (cmd) { + case ETHTOOL_GSET: + phy_ethtool_gset(phydev, &ecmd); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + + case ETHTOOL_SSET: + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) + return -EFAULT; + return phy_ethtool_sset(phydev, &ecmd); + + case ETHTOOL_NWAY_RST: + /* if autoneg is off, it's an error */ + tmp = phy_read(phydev, MII_BMCR); + if (tmp & BMCR_ANENABLE) { + tmp |= (BMCR_ANRESTART); + phy_write(phydev, MII_BMCR, tmp); + return 0; + } + return -EINVAL; + + case ETHTOOL_GLINK: + edata.data = (phy_read(phydev, + MII_BMSR) & + BMSR_LSTATUS) ? + 1 : + 0; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL(phy_ethtool_ioctl); + /** * phy_mii_ioctl - generic PHY MII ioctl interface * @phydev: the phy_device struct @@ -1213,12 +1260,16 @@ if (!phydrv->read_mmd_indirect) { struct mii_bus *bus = phydev->mdio.bus; - mutex_lock(&bus->mdio_lock); - mmd_phy_indirect(bus, prtad, devad, addr); - - /* Read the content of the MMD's selected register */ - value = bus->read(bus, addr, MII_MMD_DATA); - mutex_unlock(&bus->mdio_lock); + if (!bus->mmd_read) { + mutex_lock(&bus->mdio_lock); + mmd_phy_indirect(bus, prtad, devad, addr); + + /* Read the content of the MMD's selected register */ + value = bus->read(bus, addr, MII_MMD_DATA); + mutex_unlock(&bus->mdio_lock); + } else { + value = bus->mmd_read(bus, addr, prtad, devad); + } } else { value = phydrv->read_mmd_indirect(phydev, prtad, devad, addr); } @@ -1250,12 +1301,16 @@ if (!phydrv->write_mmd_indirect) { struct mii_bus *bus = phydev->mdio.bus; - mutex_lock(&bus->mdio_lock); - mmd_phy_indirect(bus, prtad, devad, addr); - - /* Write the data into MMD's selected register */ - bus->write(bus, addr, MII_MMD_DATA, data); - mutex_unlock(&bus->mdio_lock); + if (!bus->mmd_write) { + mutex_lock(&bus->mdio_lock); + mmd_phy_indirect(bus, prtad, devad, addr); + + /* Write the data into MMD's selected register */ + bus->write(bus, addr, MII_MMD_DATA, data); + mutex_unlock(&bus->mdio_lock); + } else { + bus->mmd_write(bus, addr, prtad, devad, data); + } } else { phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data); }