mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
usbnet: improve generic ethtool support
This adds generic support for the ethtool commands get_settings, set_settings, get_link and nway_reset to usbnet. These are now implemented using mii functions when a low-level driver supports mdio_read/mdio_write and does not override the usbnet ethtool commands with its own. Currently, this applies to the asix and the mcs7830 drivers. I have tested it on mcs7830. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: David Hollis <dhollis@davehollis.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
2a36d70834
commit
c41286fd42
4 changed files with 68 additions and 36 deletions
|
@ -700,32 +700,6 @@ static void asix_get_drvinfo (struct net_device *net,
|
|||
info->eedump_len = data->eeprom_len;
|
||||
}
|
||||
|
||||
static int asix_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
|
||||
return mii_ethtool_gset(&dev->mii,cmd);
|
||||
}
|
||||
|
||||
static int asix_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
int res = mii_ethtool_sset(&dev->mii,cmd);
|
||||
|
||||
/* link speed/duplex might have changed */
|
||||
if (dev->driver_info->link_reset)
|
||||
dev->driver_info->link_reset(dev);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int asix_nway_reset(struct net_device *net)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
|
||||
return mii_nway_restart(&dev->mii);
|
||||
}
|
||||
|
||||
static u32 asix_get_link(struct net_device *net)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
|
@ -746,15 +720,15 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
|
|||
static struct ethtool_ops ax88172_ethtool_ops = {
|
||||
.get_drvinfo = asix_get_drvinfo,
|
||||
.get_link = asix_get_link,
|
||||
.nway_reset = asix_nway_reset,
|
||||
.get_msglevel = usbnet_get_msglevel,
|
||||
.set_msglevel = usbnet_set_msglevel,
|
||||
.get_wol = asix_get_wol,
|
||||
.set_wol = asix_set_wol,
|
||||
.get_eeprom_len = asix_get_eeprom_len,
|
||||
.get_eeprom = asix_get_eeprom,
|
||||
.get_settings = asix_get_settings,
|
||||
.set_settings = asix_set_settings,
|
||||
.get_settings = usbnet_get_settings,
|
||||
.set_settings = usbnet_set_settings,
|
||||
.nway_reset = usbnet_nway_reset,
|
||||
};
|
||||
|
||||
static void ax88172_set_multicast(struct net_device *net)
|
||||
|
@ -885,15 +859,15 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
static struct ethtool_ops ax88772_ethtool_ops = {
|
||||
.get_drvinfo = asix_get_drvinfo,
|
||||
.get_link = asix_get_link,
|
||||
.nway_reset = asix_nway_reset,
|
||||
.get_msglevel = usbnet_get_msglevel,
|
||||
.set_msglevel = usbnet_set_msglevel,
|
||||
.get_wol = asix_get_wol,
|
||||
.set_wol = asix_set_wol,
|
||||
.get_eeprom_len = asix_get_eeprom_len,
|
||||
.get_eeprom = asix_get_eeprom,
|
||||
.get_settings = asix_get_settings,
|
||||
.set_settings = asix_set_settings,
|
||||
.get_settings = usbnet_get_settings,
|
||||
.set_settings = usbnet_set_settings,
|
||||
.nway_reset = usbnet_nway_reset,
|
||||
};
|
||||
|
||||
static int ax88772_link_reset(struct usbnet *dev)
|
||||
|
@ -1046,15 +1020,15 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
static struct ethtool_ops ax88178_ethtool_ops = {
|
||||
.get_drvinfo = asix_get_drvinfo,
|
||||
.get_link = asix_get_link,
|
||||
.nway_reset = asix_nway_reset,
|
||||
.get_msglevel = usbnet_get_msglevel,
|
||||
.set_msglevel = usbnet_set_msglevel,
|
||||
.get_wol = asix_get_wol,
|
||||
.set_wol = asix_set_wol,
|
||||
.get_eeprom_len = asix_get_eeprom_len,
|
||||
.get_eeprom = asix_get_eeprom,
|
||||
.get_settings = asix_get_settings,
|
||||
.set_settings = asix_set_settings,
|
||||
.get_settings = usbnet_get_settings,
|
||||
.set_settings = usbnet_set_settings,
|
||||
.nway_reset = usbnet_nway_reset,
|
||||
};
|
||||
|
||||
static int marvell_phy_init(struct usbnet *dev)
|
||||
|
|
|
@ -430,8 +430,12 @@ static struct ethtool_ops mcs7830_ethtool_ops = {
|
|||
.get_regs = mcs7830_get_regs,
|
||||
|
||||
/* common usbnet calls */
|
||||
.get_link = usbnet_get_link,
|
||||
.get_msglevel = usbnet_get_msglevel,
|
||||
.set_msglevel = usbnet_set_msglevel,
|
||||
.get_settings = usbnet_get_settings,
|
||||
.set_settings = usbnet_set_settings,
|
||||
.nway_reset = usbnet_nway_reset,
|
||||
};
|
||||
|
||||
static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
|
||||
|
|
|
@ -669,6 +669,37 @@ static int usbnet_open (struct net_device *net)
|
|||
* they'll probably want to use this base set.
|
||||
*/
|
||||
|
||||
int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
|
||||
if (!dev->mii.mdio_read)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return mii_ethtool_gset(&dev->mii, cmd);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_get_settings);
|
||||
|
||||
int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
int retval;
|
||||
|
||||
if (!dev->mii.mdio_write)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
retval = mii_ethtool_sset(&dev->mii, cmd);
|
||||
|
||||
/* link speed/duplex might have changed */
|
||||
if (dev->driver_info->link_reset)
|
||||
dev->driver_info->link_reset(dev);
|
||||
|
||||
return retval;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_set_settings);
|
||||
|
||||
|
||||
void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
|
@ -682,7 +713,7 @@ void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
|
||||
|
||||
static u32 usbnet_get_link (struct net_device *net)
|
||||
u32 usbnet_get_link (struct net_device *net)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
|
||||
|
@ -690,9 +721,14 @@ static u32 usbnet_get_link (struct net_device *net)
|
|||
if (dev->driver_info->check_connect)
|
||||
return dev->driver_info->check_connect (dev) == 0;
|
||||
|
||||
/* if the device has mii operations, use those */
|
||||
if (dev->mii.mdio_read)
|
||||
return mii_link_ok(&dev->mii);
|
||||
|
||||
/* Otherwise, say we're up (to avoid breaking scripts) */
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_get_link);
|
||||
|
||||
u32 usbnet_get_msglevel (struct net_device *net)
|
||||
{
|
||||
|
@ -710,10 +746,24 @@ void usbnet_set_msglevel (struct net_device *net, u32 level)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
|
||||
|
||||
int usbnet_nway_reset(struct net_device *net)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
|
||||
if (!dev->mii.mdio_write)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return mii_nway_restart(&dev->mii);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_nway_reset);
|
||||
|
||||
/* drivers may override default ethtool_ops in their bind() routine */
|
||||
static struct ethtool_ops usbnet_ethtool_ops = {
|
||||
.get_settings = usbnet_get_settings,
|
||||
.set_settings = usbnet_set_settings,
|
||||
.get_drvinfo = usbnet_get_drvinfo,
|
||||
.get_link = usbnet_get_link,
|
||||
.nway_reset = usbnet_nway_reset,
|
||||
.get_msglevel = usbnet_get_msglevel,
|
||||
.set_msglevel = usbnet_set_msglevel,
|
||||
};
|
||||
|
|
|
@ -168,9 +168,13 @@ extern void usbnet_defer_kevent (struct usbnet *, int);
|
|||
extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
|
||||
extern void usbnet_unlink_rx_urbs(struct usbnet *);
|
||||
|
||||
extern int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd);
|
||||
extern int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd);
|
||||
extern u32 usbnet_get_link (struct net_device *net);
|
||||
extern u32 usbnet_get_msglevel (struct net_device *);
|
||||
extern void usbnet_set_msglevel (struct net_device *, u32);
|
||||
extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
|
||||
extern int usbnet_nway_reset(struct net_device *net);
|
||||
|
||||
/* messaging support includes the interface name, so it must not be
|
||||
* used before it has one ... notably, in minidriver bind() calls.
|
||||
|
|
Loading…
Reference in a new issue