1 From: John Crispin <john@phrozen.org>
2 Subject: net: phy: add phy_ethtool_ioctl()
4 Signed-off-by: John Crispin <john@phrozen.org>
6 drivers/net/phy/phy.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
7 include/linux/phy.h | 1 +
8 2 files changed, 45 insertions(+)
10 --- a/drivers/net/phy/phy.c
11 +++ b/drivers/net/phy/phy.c
12 @@ -382,6 +382,73 @@ void phy_ethtool_ksettings_get(struct ph
14 EXPORT_SYMBOL(phy_ethtool_ksettings_get);
16 +static int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
18 + cmd->supported = phydev->supported;
20 + cmd->advertising = phydev->advertising;
21 + cmd->lp_advertising = phydev->lp_advertising;
23 + ethtool_cmd_speed_set(cmd, phydev->speed);
24 + cmd->duplex = phydev->duplex;
25 + if (phydev->interface == PHY_INTERFACE_MODE_MOCA)
26 + cmd->port = PORT_BNC;
28 + cmd->port = PORT_MII;
29 + cmd->phy_address = phydev->mdio.addr;
30 + cmd->transceiver = phy_is_internal(phydev) ?
31 + XCVR_INTERNAL : XCVR_EXTERNAL;
32 + cmd->autoneg = phydev->autoneg;
33 + cmd->eth_tp_mdix_ctrl = phydev->mdix_ctrl;
34 + cmd->eth_tp_mdix = phydev->mdix;
39 +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
43 + struct ethtool_cmd ecmd = { ETHTOOL_GSET };
44 + struct ethtool_value edata = { ETHTOOL_GLINK };
46 + if (get_user(cmd, (u32 *) useraddr))
51 + phy_ethtool_gset(phydev, &ecmd);
52 + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
57 + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
59 + return phy_ethtool_sset(phydev, &ecmd);
61 + case ETHTOOL_NWAY_RST:
62 + /* if autoneg is off, it's an error */
63 + tmp = phy_read(phydev, MII_BMCR);
64 + if (tmp & BMCR_ANENABLE) {
65 + tmp |= (BMCR_ANRESTART);
66 + phy_write(phydev, MII_BMCR, tmp);
72 + edata.data = (phy_read(phydev,
73 + MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
74 + if (copy_to_user(useraddr, &edata, sizeof(edata)))
81 +EXPORT_SYMBOL(phy_ethtool_ioctl);
84 * phy_mii_ioctl - generic PHY MII ioctl interface
85 * @phydev: the phy_device struct
86 --- a/include/linux/phy.h
87 +++ b/include/linux/phy.h
88 @@ -909,6 +909,7 @@ void phy_ethtool_ksettings_get(struct ph
89 struct ethtool_link_ksettings *cmd);
90 int phy_ethtool_ksettings_set(struct phy_device *phydev,
91 const struct ethtool_link_ksettings *cmd);
92 +int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
93 int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
94 int phy_start_interrupts(struct phy_device *phydev);
95 void phy_print_status(struct phy_device *phydev);