0002-phy-add-ethtool-ioctl-support-used-by-ag71xx-driver.patch 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. From 7b864612a6e3b139a5a607abd0048a19078fe42f Mon Sep 17 00:00:00 2001
  2. From: Phil Sutter <phil@nwl.cc>
  3. Date: Wed, 14 May 2014 02:55:06 +0200
  4. Subject: [PATCH] phy: add ethtool ioctl support, used by ag71xx driver
  5. ---
  6. drivers/net/phy/phy.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
  7. include/linux/phy.h | 1 +
  8. 2 files changed, 45 insertions(+)
  9. diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
  10. index 76d96b9..9439ef3 100644
  11. --- a/drivers/net/phy/phy.c
  12. +++ b/drivers/net/phy/phy.c
  13. @@ -293,6 +293,50 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
  14. }
  15. EXPORT_SYMBOL(phy_ethtool_gset);
  16. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
  17. +{
  18. + u32 cmd;
  19. + int tmp;
  20. + struct ethtool_cmd ecmd = { ETHTOOL_GSET };
  21. + struct ethtool_value edata = { ETHTOOL_GLINK };
  22. +
  23. + if (get_user(cmd, (u32 *) useraddr))
  24. + return -EFAULT;
  25. +
  26. + switch (cmd) {
  27. + case ETHTOOL_GSET:
  28. + phy_ethtool_gset(phydev, &ecmd);
  29. + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
  30. + return -EFAULT;
  31. + return 0;
  32. +
  33. + case ETHTOOL_SSET:
  34. + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
  35. + return -EFAULT;
  36. + return phy_ethtool_sset(phydev, &ecmd);
  37. +
  38. + case ETHTOOL_NWAY_RST:
  39. + /* if autoneg is off, it's an error */
  40. + tmp = phy_read(phydev, MII_BMCR);
  41. + if (tmp & BMCR_ANENABLE) {
  42. + tmp |= (BMCR_ANRESTART);
  43. + phy_write(phydev, MII_BMCR, tmp);
  44. + return 0;
  45. + }
  46. + return -EINVAL;
  47. +
  48. + case ETHTOOL_GLINK:
  49. + edata.data = (phy_read(phydev,
  50. + MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
  51. + if (copy_to_user(useraddr, &edata, sizeof(edata)))
  52. + return -EFAULT;
  53. + return 0;
  54. + }
  55. +
  56. + return -EOPNOTSUPP;
  57. +}
  58. +EXPORT_SYMBOL(phy_ethtool_ioctl);
  59. +
  60. /**
  61. * phy_mii_ioctl - generic PHY MII ioctl interface
  62. * @phydev: the phy_device struct
  63. diff --git a/include/linux/phy.h b/include/linux/phy.h
  64. index 565188c..9ab0d79 100644
  65. --- a/include/linux/phy.h
  66. +++ b/include/linux/phy.h
  67. @@ -628,6 +628,7 @@ void phy_stop_machine(struct phy_device *phydev);
  68. int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  69. int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
  70. int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
  71. +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
  72. int phy_start_interrupts(struct phy_device *phydev);
  73. void phy_print_status(struct phy_device *phydev);
  74. void phy_device_free(struct phy_device *phydev);
  75. --
  76. 1.8.5.3