--- zzzz-none-000/linux-4.4.60/drivers/net/phy/phy.c 2017-04-08 07:53:53.000000000 +0000 +++ dragonfly-4020-701/linux-4.4.60/drivers/net/phy/phy.c 2018-11-08 13:36:17.000000000 +0000 @@ -385,6 +385,50 @@ } EXPORT_SYMBOL(phy_ethtool_gset); +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 @@ -524,6 +568,7 @@ { queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, HZ); } +EXPORT_SYMBOL(phy_start_machine); /** * phy_stop_machine - stop the PHY state machine tracking @@ -542,6 +587,7 @@ phydev->state = PHY_UP; mutex_unlock(&phydev->lock); } +EXPORT_SYMBOL(phy_stop_machine); /** * phy_error - enter HALTED state for this PHY device