]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
net: core: 'ethtool' issue with querying phy settings
authorArun Parameswaran <aparames@broadcom.com>
Wed, 20 May 2015 21:35:30 +0000 (14:35 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 22 May 2015 20:14:17 +0000 (16:14 -0400)
When trying to configure the settings for PHY1, using commands
like 'ethtool -s eth0 phyad 1 speed 100', the 'ethtool' seems to
modify other settings apart from the speed of the PHY1, in the
above case.

The ethtool seems to query the settings for PHY0, and use this
as the base to apply the new settings to the PHY1. This is
causing the other settings of the PHY 1 to be wrongly
configured.

The issue is caused by the '_ethtool_get_settings()' API, which
gets called because of the 'ETHTOOL_GSET' command, is clearing
the 'cmd' pointer (of type 'struct ethtool_cmd') by calling
memset. This clears all the parameters (if any) passed for the
'ETHTOOL_GSET' cmd. So the driver's callback is always invoked
with 'cmd->phy_address' as '0'.

The '_ethtool_get_settings()' is called from other files in the
'net/core'. So the fix is applied to the 'ethtool_get_settings()'
which is only called in the context of the 'ethtool'.

Signed-off-by: Arun Parameswaran <aparames@broadcom.com>
Reviewed-by: Ray Jui <rjui@broadcom.com>
Reviewed-by: Scott Branden <sbranden@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/ethtool.c

index 1d00b89229024b45fef3955cd27221fafe2bfb74..1347e11f5cc9b0aa6ef8485cf44feaa1965a04e9 100644 (file)
@@ -359,7 +359,15 @@ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
        int err;
        struct ethtool_cmd cmd;
 
        int err;
        struct ethtool_cmd cmd;
 
-       err = __ethtool_get_settings(dev, &cmd);
+       if (!dev->ethtool_ops->get_settings)
+               return -EOPNOTSUPP;
+
+       if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
+               return -EFAULT;
+
+       cmd.cmd = ETHTOOL_GSET;
+
+       err = dev->ethtool_ops->get_settings(dev, &cmd);
        if (err < 0)
                return err;
 
        if (err < 0)
                return err;