diff options
author | Arnd Bergmann <arnd@arndb.de> | 2006-10-08 18:08:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-10-17 17:46:32 -0400 |
commit | c41286fd42f3545513f8de9f61028120b6d38e89 (patch) | |
tree | 2dddcf5c7423c0db62a1f8752c002cf62080287b | |
parent | 2a36d7083438ccb607055abae633f39495a99947 (diff) |
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>
-rw-r--r-- | drivers/usb/net/asix.c | 44 | ||||
-rw-r--r-- | drivers/usb/net/mcs7830.c | 4 | ||||
-rw-r--r-- | drivers/usb/net/usbnet.c | 52 | ||||
-rw-r--r-- | drivers/usb/net/usbnet.h | 4 |
4 files changed, 68 insertions, 36 deletions
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index c73dd224aa76..5edd0534c7ab 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c | |||
@@ -700,32 +700,6 @@ static void asix_get_drvinfo (struct net_device *net, | |||
700 | info->eedump_len = data->eeprom_len; | 700 | info->eedump_len = data->eeprom_len; |
701 | } | 701 | } |
702 | 702 | ||
703 | static int asix_get_settings(struct net_device *net, struct ethtool_cmd *cmd) | ||
704 | { | ||
705 | struct usbnet *dev = netdev_priv(net); | ||
706 | |||
707 | return mii_ethtool_gset(&dev->mii,cmd); | ||
708 | } | ||
709 | |||
710 | static int asix_set_settings(struct net_device *net, struct ethtool_cmd *cmd) | ||
711 | { | ||
712 | struct usbnet *dev = netdev_priv(net); | ||
713 | int res = mii_ethtool_sset(&dev->mii,cmd); | ||
714 | |||
715 | /* link speed/duplex might have changed */ | ||
716 | if (dev->driver_info->link_reset) | ||
717 | dev->driver_info->link_reset(dev); | ||
718 | |||
719 | return res; | ||
720 | } | ||
721 | |||
722 | static int asix_nway_reset(struct net_device *net) | ||
723 | { | ||
724 | struct usbnet *dev = netdev_priv(net); | ||
725 | |||
726 | return mii_nway_restart(&dev->mii); | ||
727 | } | ||
728 | |||
729 | static u32 asix_get_link(struct net_device *net) | 703 | static u32 asix_get_link(struct net_device *net) |
730 | { | 704 | { |
731 | struct usbnet *dev = netdev_priv(net); | 705 | struct usbnet *dev = netdev_priv(net); |
@@ -746,15 +720,15 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) | |||
746 | static struct ethtool_ops ax88172_ethtool_ops = { | 720 | static struct ethtool_ops ax88172_ethtool_ops = { |
747 | .get_drvinfo = asix_get_drvinfo, | 721 | .get_drvinfo = asix_get_drvinfo, |
748 | .get_link = asix_get_link, | 722 | .get_link = asix_get_link, |
749 | .nway_reset = asix_nway_reset, | ||
750 | .get_msglevel = usbnet_get_msglevel, | 723 | .get_msglevel = usbnet_get_msglevel, |
751 | .set_msglevel = usbnet_set_msglevel, | 724 | .set_msglevel = usbnet_set_msglevel, |
752 | .get_wol = asix_get_wol, | 725 | .get_wol = asix_get_wol, |
753 | .set_wol = asix_set_wol, | 726 | .set_wol = asix_set_wol, |
754 | .get_eeprom_len = asix_get_eeprom_len, | 727 | .get_eeprom_len = asix_get_eeprom_len, |
755 | .get_eeprom = asix_get_eeprom, | 728 | .get_eeprom = asix_get_eeprom, |
756 | .get_settings = asix_get_settings, | 729 | .get_settings = usbnet_get_settings, |
757 | .set_settings = asix_set_settings, | 730 | .set_settings = usbnet_set_settings, |
731 | .nway_reset = usbnet_nway_reset, | ||
758 | }; | 732 | }; |
759 | 733 | ||
760 | static void ax88172_set_multicast(struct net_device *net) | 734 | static void ax88172_set_multicast(struct net_device *net) |
@@ -885,15 +859,15 @@ out1: | |||
885 | static struct ethtool_ops ax88772_ethtool_ops = { | 859 | static struct ethtool_ops ax88772_ethtool_ops = { |
886 | .get_drvinfo = asix_get_drvinfo, | 860 | .get_drvinfo = asix_get_drvinfo, |
887 | .get_link = asix_get_link, | 861 | .get_link = asix_get_link, |
888 | .nway_reset = asix_nway_reset, | ||
889 | .get_msglevel = usbnet_get_msglevel, | 862 | .get_msglevel = usbnet_get_msglevel, |
890 | .set_msglevel = usbnet_set_msglevel, | 863 | .set_msglevel = usbnet_set_msglevel, |
891 | .get_wol = asix_get_wol, | 864 | .get_wol = asix_get_wol, |
892 | .set_wol = asix_set_wol, | 865 | .set_wol = asix_set_wol, |
893 | .get_eeprom_len = asix_get_eeprom_len, | 866 | .get_eeprom_len = asix_get_eeprom_len, |
894 | .get_eeprom = asix_get_eeprom, | 867 | .get_eeprom = asix_get_eeprom, |
895 | .get_settings = asix_get_settings, | 868 | .get_settings = usbnet_get_settings, |
896 | .set_settings = asix_set_settings, | 869 | .set_settings = usbnet_set_settings, |
870 | .nway_reset = usbnet_nway_reset, | ||
897 | }; | 871 | }; |
898 | 872 | ||
899 | static int ax88772_link_reset(struct usbnet *dev) | 873 | static int ax88772_link_reset(struct usbnet *dev) |
@@ -1046,15 +1020,15 @@ out1: | |||
1046 | static struct ethtool_ops ax88178_ethtool_ops = { | 1020 | static struct ethtool_ops ax88178_ethtool_ops = { |
1047 | .get_drvinfo = asix_get_drvinfo, | 1021 | .get_drvinfo = asix_get_drvinfo, |
1048 | .get_link = asix_get_link, | 1022 | .get_link = asix_get_link, |
1049 | .nway_reset = asix_nway_reset, | ||
1050 | .get_msglevel = usbnet_get_msglevel, | 1023 | .get_msglevel = usbnet_get_msglevel, |
1051 | .set_msglevel = usbnet_set_msglevel, | 1024 | .set_msglevel = usbnet_set_msglevel, |
1052 | .get_wol = asix_get_wol, | 1025 | .get_wol = asix_get_wol, |
1053 | .set_wol = asix_set_wol, | 1026 | .set_wol = asix_set_wol, |
1054 | .get_eeprom_len = asix_get_eeprom_len, | 1027 | .get_eeprom_len = asix_get_eeprom_len, |
1055 | .get_eeprom = asix_get_eeprom, | 1028 | .get_eeprom = asix_get_eeprom, |
1056 | .get_settings = asix_get_settings, | 1029 | .get_settings = usbnet_get_settings, |
1057 | .set_settings = asix_set_settings, | 1030 | .set_settings = usbnet_set_settings, |
1031 | .nway_reset = usbnet_nway_reset, | ||
1058 | }; | 1032 | }; |
1059 | 1033 | ||
1060 | static int marvell_phy_init(struct usbnet *dev) | 1034 | static int marvell_phy_init(struct usbnet *dev) |
diff --git a/drivers/usb/net/mcs7830.c b/drivers/usb/net/mcs7830.c index 0266090a1d7d..23a80667f17e 100644 --- a/drivers/usb/net/mcs7830.c +++ b/drivers/usb/net/mcs7830.c | |||
@@ -430,8 +430,12 @@ static struct ethtool_ops mcs7830_ethtool_ops = { | |||
430 | .get_regs = mcs7830_get_regs, | 430 | .get_regs = mcs7830_get_regs, |
431 | 431 | ||
432 | /* common usbnet calls */ | 432 | /* common usbnet calls */ |
433 | .get_link = usbnet_get_link, | ||
433 | .get_msglevel = usbnet_get_msglevel, | 434 | .get_msglevel = usbnet_get_msglevel, |
434 | .set_msglevel = usbnet_set_msglevel, | 435 | .set_msglevel = usbnet_set_msglevel, |
436 | .get_settings = usbnet_get_settings, | ||
437 | .set_settings = usbnet_set_settings, | ||
438 | .nway_reset = usbnet_nway_reset, | ||
435 | }; | 439 | }; |
436 | 440 | ||
437 | static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev) | 441 | static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev) |
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index af6d061dc79b..decc1b179246 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -669,6 +669,37 @@ done: | |||
669 | * they'll probably want to use this base set. | 669 | * they'll probably want to use this base set. |
670 | */ | 670 | */ |
671 | 671 | ||
672 | int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd) | ||
673 | { | ||
674 | struct usbnet *dev = netdev_priv(net); | ||
675 | |||
676 | if (!dev->mii.mdio_read) | ||
677 | return -EOPNOTSUPP; | ||
678 | |||
679 | return mii_ethtool_gset(&dev->mii, cmd); | ||
680 | } | ||
681 | EXPORT_SYMBOL_GPL(usbnet_get_settings); | ||
682 | |||
683 | int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd) | ||
684 | { | ||
685 | struct usbnet *dev = netdev_priv(net); | ||
686 | int retval; | ||
687 | |||
688 | if (!dev->mii.mdio_write) | ||
689 | return -EOPNOTSUPP; | ||
690 | |||
691 | retval = mii_ethtool_sset(&dev->mii, cmd); | ||
692 | |||
693 | /* link speed/duplex might have changed */ | ||
694 | if (dev->driver_info->link_reset) | ||
695 | dev->driver_info->link_reset(dev); | ||
696 | |||
697 | return retval; | ||
698 | |||
699 | } | ||
700 | EXPORT_SYMBOL_GPL(usbnet_set_settings); | ||
701 | |||
702 | |||
672 | void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) | 703 | void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) |
673 | { | 704 | { |
674 | struct usbnet *dev = netdev_priv(net); | 705 | struct usbnet *dev = netdev_priv(net); |
@@ -682,7 +713,7 @@ void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) | |||
682 | } | 713 | } |
683 | EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); | 714 | EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); |
684 | 715 | ||
685 | static u32 usbnet_get_link (struct net_device *net) | 716 | u32 usbnet_get_link (struct net_device *net) |
686 | { | 717 | { |
687 | struct usbnet *dev = netdev_priv(net); | 718 | struct usbnet *dev = netdev_priv(net); |
688 | 719 | ||
@@ -690,9 +721,14 @@ static u32 usbnet_get_link (struct net_device *net) | |||
690 | if (dev->driver_info->check_connect) | 721 | if (dev->driver_info->check_connect) |
691 | return dev->driver_info->check_connect (dev) == 0; | 722 | return dev->driver_info->check_connect (dev) == 0; |
692 | 723 | ||
724 | /* if the device has mii operations, use those */ | ||
725 | if (dev->mii.mdio_read) | ||
726 | return mii_link_ok(&dev->mii); | ||
727 | |||
693 | /* Otherwise, say we're up (to avoid breaking scripts) */ | 728 | /* Otherwise, say we're up (to avoid breaking scripts) */ |
694 | return 1; | 729 | return 1; |
695 | } | 730 | } |
731 | EXPORT_SYMBOL_GPL(usbnet_get_link); | ||
696 | 732 | ||
697 | u32 usbnet_get_msglevel (struct net_device *net) | 733 | u32 usbnet_get_msglevel (struct net_device *net) |
698 | { | 734 | { |
@@ -710,10 +746,24 @@ void usbnet_set_msglevel (struct net_device *net, u32 level) | |||
710 | } | 746 | } |
711 | EXPORT_SYMBOL_GPL(usbnet_set_msglevel); | 747 | EXPORT_SYMBOL_GPL(usbnet_set_msglevel); |
712 | 748 | ||
749 | int usbnet_nway_reset(struct net_device *net) | ||
750 | { | ||
751 | struct usbnet *dev = netdev_priv(net); | ||
752 | |||
753 | if (!dev->mii.mdio_write) | ||
754 | return -EOPNOTSUPP; | ||
755 | |||
756 | return mii_nway_restart(&dev->mii); | ||
757 | } | ||
758 | EXPORT_SYMBOL_GPL(usbnet_nway_reset); | ||
759 | |||
713 | /* drivers may override default ethtool_ops in their bind() routine */ | 760 | /* drivers may override default ethtool_ops in their bind() routine */ |
714 | static struct ethtool_ops usbnet_ethtool_ops = { | 761 | static struct ethtool_ops usbnet_ethtool_ops = { |
762 | .get_settings = usbnet_get_settings, | ||
763 | .set_settings = usbnet_set_settings, | ||
715 | .get_drvinfo = usbnet_get_drvinfo, | 764 | .get_drvinfo = usbnet_get_drvinfo, |
716 | .get_link = usbnet_get_link, | 765 | .get_link = usbnet_get_link, |
766 | .nway_reset = usbnet_nway_reset, | ||
717 | .get_msglevel = usbnet_get_msglevel, | 767 | .get_msglevel = usbnet_get_msglevel, |
718 | .set_msglevel = usbnet_set_msglevel, | 768 | .set_msglevel = usbnet_set_msglevel, |
719 | }; | 769 | }; |
diff --git a/drivers/usb/net/usbnet.h b/drivers/usb/net/usbnet.h index c0746f0454af..743947c3fb83 100644 --- a/drivers/usb/net/usbnet.h +++ b/drivers/usb/net/usbnet.h | |||
@@ -168,9 +168,13 @@ extern void usbnet_defer_kevent (struct usbnet *, int); | |||
168 | extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); | 168 | extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); |
169 | extern void usbnet_unlink_rx_urbs(struct usbnet *); | 169 | extern void usbnet_unlink_rx_urbs(struct usbnet *); |
170 | 170 | ||
171 | extern int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd); | ||
172 | extern int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd); | ||
173 | extern u32 usbnet_get_link (struct net_device *net); | ||
171 | extern u32 usbnet_get_msglevel (struct net_device *); | 174 | extern u32 usbnet_get_msglevel (struct net_device *); |
172 | extern void usbnet_set_msglevel (struct net_device *, u32); | 175 | extern void usbnet_set_msglevel (struct net_device *, u32); |
173 | extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *); | 176 | extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *); |
177 | extern int usbnet_nway_reset(struct net_device *net); | ||
174 | 178 | ||
175 | /* messaging support includes the interface name, so it must not be | 179 | /* messaging support includes the interface name, so it must not be |
176 | * used before it has one ... notably, in minidriver bind() calls. | 180 | * used before it has one ... notably, in minidriver bind() calls. |