701-phy_extension.patch 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. --- a/drivers/net/phy/phy.c
  2. +++ b/drivers/net/phy/phy.c
  3. @@ -357,6 +357,50 @@ int phy_ethtool_gset(struct phy_device *
  4. }
  5. EXPORT_SYMBOL(phy_ethtool_gset);
  6. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
  7. +{
  8. + u32 cmd;
  9. + int tmp;
  10. + struct ethtool_cmd ecmd = { ETHTOOL_GSET };
  11. + struct ethtool_value edata = { ETHTOOL_GLINK };
  12. +
  13. + if (get_user(cmd, (u32 *) useraddr))
  14. + return -EFAULT;
  15. +
  16. + switch (cmd) {
  17. + case ETHTOOL_GSET:
  18. + phy_ethtool_gset(phydev, &ecmd);
  19. + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
  20. + return -EFAULT;
  21. + return 0;
  22. +
  23. + case ETHTOOL_SSET:
  24. + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
  25. + return -EFAULT;
  26. + return phy_ethtool_sset(phydev, &ecmd);
  27. +
  28. + case ETHTOOL_NWAY_RST:
  29. + /* if autoneg is off, it's an error */
  30. + tmp = phy_read(phydev, MII_BMCR);
  31. + if (tmp & BMCR_ANENABLE) {
  32. + tmp |= (BMCR_ANRESTART);
  33. + phy_write(phydev, MII_BMCR, tmp);
  34. + return 0;
  35. + }
  36. + return -EINVAL;
  37. +
  38. + case ETHTOOL_GLINK:
  39. + edata.data = (phy_read(phydev,
  40. + MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
  41. + if (copy_to_user(useraddr, &edata, sizeof(edata)))
  42. + return -EFAULT;
  43. + return 0;
  44. + }
  45. +
  46. + return -EOPNOTSUPP;
  47. +}
  48. +EXPORT_SYMBOL(phy_ethtool_ioctl);
  49. +
  50. /**
  51. * phy_mii_ioctl - generic PHY MII ioctl interface
  52. * @phydev: the phy_device struct
  53. --- a/include/linux/phy.h
  54. +++ b/include/linux/phy.h
  55. @@ -748,6 +748,7 @@ void phy_start_machine(struct phy_device
  56. void phy_stop_machine(struct phy_device *phydev);
  57. int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  58. int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  59. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
  60. int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
  61. int phy_start_interrupts(struct phy_device *phydev);
  62. void phy_print_status(struct phy_device *phydev);