diff options
Diffstat (limited to 'drivers/usb/net/usbnet.c')
-rw-r--r-- | drivers/usb/net/usbnet.c | 81 |
1 files changed, 69 insertions, 12 deletions
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 24bd3486ee63..760b5327b81b 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -554,7 +554,7 @@ static int usbnet_stop (struct net_device *net) | |||
554 | { | 554 | { |
555 | struct usbnet *dev = netdev_priv(net); | 555 | struct usbnet *dev = netdev_priv(net); |
556 | int temp; | 556 | int temp; |
557 | DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); | 557 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup); |
558 | DECLARE_WAITQUEUE (wait, current); | 558 | DECLARE_WAITQUEUE (wait, current); |
559 | 559 | ||
560 | netif_stop_queue (net); | 560 | netif_stop_queue (net); |
@@ -669,20 +669,40 @@ 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 | void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) | 672 | #if defined(CONFIG_MII) || defined(CONFIG_MII_MODULE) |
673 | #define HAVE_MII | ||
674 | |||
675 | int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd) | ||
673 | { | 676 | { |
674 | struct usbnet *dev = netdev_priv(net); | 677 | struct usbnet *dev = netdev_priv(net); |
675 | 678 | ||
676 | /* REVISIT don't always return "usbnet" */ | 679 | if (!dev->mii.mdio_read) |
677 | strncpy (info->driver, driver_name, sizeof info->driver); | 680 | return -EOPNOTSUPP; |
678 | strncpy (info->version, DRIVER_VERSION, sizeof info->version); | 681 | |
679 | strncpy (info->fw_version, dev->driver_info->description, | 682 | return mii_ethtool_gset(&dev->mii, cmd); |
680 | sizeof info->fw_version); | ||
681 | usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); | ||
682 | } | 683 | } |
683 | EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); | 684 | EXPORT_SYMBOL_GPL(usbnet_get_settings); |
685 | |||
686 | int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd) | ||
687 | { | ||
688 | struct usbnet *dev = netdev_priv(net); | ||
689 | int retval; | ||
690 | |||
691 | if (!dev->mii.mdio_write) | ||
692 | return -EOPNOTSUPP; | ||
684 | 693 | ||
685 | static u32 usbnet_get_link (struct net_device *net) | 694 | retval = mii_ethtool_sset(&dev->mii, cmd); |
695 | |||
696 | /* link speed/duplex might have changed */ | ||
697 | if (dev->driver_info->link_reset) | ||
698 | dev->driver_info->link_reset(dev); | ||
699 | |||
700 | return retval; | ||
701 | |||
702 | } | ||
703 | EXPORT_SYMBOL_GPL(usbnet_set_settings); | ||
704 | |||
705 | u32 usbnet_get_link (struct net_device *net) | ||
686 | { | 706 | { |
687 | struct usbnet *dev = netdev_priv(net); | 707 | struct usbnet *dev = netdev_priv(net); |
688 | 708 | ||
@@ -690,9 +710,40 @@ static u32 usbnet_get_link (struct net_device *net) | |||
690 | if (dev->driver_info->check_connect) | 710 | if (dev->driver_info->check_connect) |
691 | return dev->driver_info->check_connect (dev) == 0; | 711 | return dev->driver_info->check_connect (dev) == 0; |
692 | 712 | ||
713 | /* if the device has mii operations, use those */ | ||
714 | if (dev->mii.mdio_read) | ||
715 | return mii_link_ok(&dev->mii); | ||
716 | |||
693 | /* Otherwise, say we're up (to avoid breaking scripts) */ | 717 | /* Otherwise, say we're up (to avoid breaking scripts) */ |
694 | return 1; | 718 | return 1; |
695 | } | 719 | } |
720 | EXPORT_SYMBOL_GPL(usbnet_get_link); | ||
721 | |||
722 | int usbnet_nway_reset(struct net_device *net) | ||
723 | { | ||
724 | struct usbnet *dev = netdev_priv(net); | ||
725 | |||
726 | if (!dev->mii.mdio_write) | ||
727 | return -EOPNOTSUPP; | ||
728 | |||
729 | return mii_nway_restart(&dev->mii); | ||
730 | } | ||
731 | EXPORT_SYMBOL_GPL(usbnet_nway_reset); | ||
732 | |||
733 | #endif /* HAVE_MII */ | ||
734 | |||
735 | void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) | ||
736 | { | ||
737 | struct usbnet *dev = netdev_priv(net); | ||
738 | |||
739 | /* REVISIT don't always return "usbnet" */ | ||
740 | strncpy (info->driver, driver_name, sizeof info->driver); | ||
741 | strncpy (info->version, DRIVER_VERSION, sizeof info->version); | ||
742 | strncpy (info->fw_version, dev->driver_info->description, | ||
743 | sizeof info->fw_version); | ||
744 | usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); | ||
745 | } | ||
746 | EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); | ||
696 | 747 | ||
697 | u32 usbnet_get_msglevel (struct net_device *net) | 748 | u32 usbnet_get_msglevel (struct net_device *net) |
698 | { | 749 | { |
@@ -712,8 +763,13 @@ EXPORT_SYMBOL_GPL(usbnet_set_msglevel); | |||
712 | 763 | ||
713 | /* drivers may override default ethtool_ops in their bind() routine */ | 764 | /* drivers may override default ethtool_ops in their bind() routine */ |
714 | static struct ethtool_ops usbnet_ethtool_ops = { | 765 | static struct ethtool_ops usbnet_ethtool_ops = { |
715 | .get_drvinfo = usbnet_get_drvinfo, | 766 | #ifdef HAVE_MII |
767 | .get_settings = usbnet_get_settings, | ||
768 | .set_settings = usbnet_set_settings, | ||
716 | .get_link = usbnet_get_link, | 769 | .get_link = usbnet_get_link, |
770 | .nway_reset = usbnet_nway_reset, | ||
771 | #endif | ||
772 | .get_drvinfo = usbnet_get_drvinfo, | ||
717 | .get_msglevel = usbnet_get_msglevel, | 773 | .get_msglevel = usbnet_get_msglevel, |
718 | .set_msglevel = usbnet_set_msglevel, | 774 | .set_msglevel = usbnet_set_msglevel, |
719 | }; | 775 | }; |
@@ -1094,6 +1150,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1094 | dev->delay.function = usbnet_bh; | 1150 | dev->delay.function = usbnet_bh; |
1095 | dev->delay.data = (unsigned long) dev; | 1151 | dev->delay.data = (unsigned long) dev; |
1096 | init_timer (&dev->delay); | 1152 | init_timer (&dev->delay); |
1153 | mutex_init (&dev->phy_mutex); | ||
1097 | 1154 | ||
1098 | SET_MODULE_OWNER (net); | 1155 | SET_MODULE_OWNER (net); |
1099 | dev->net = net; | 1156 | dev->net = net; |
@@ -1225,7 +1282,7 @@ EXPORT_SYMBOL_GPL(usbnet_resume); | |||
1225 | static int __init usbnet_init(void) | 1282 | static int __init usbnet_init(void) |
1226 | { | 1283 | { |
1227 | /* compiler should optimize this out */ | 1284 | /* compiler should optimize this out */ |
1228 | BUG_ON (sizeof (((struct sk_buff *)0)->cb) | 1285 | BUILD_BUG_ON (sizeof (((struct sk_buff *)0)->cb) |
1229 | < sizeof (struct skb_data)); | 1286 | < sizeof (struct skb_data)); |
1230 | 1287 | ||
1231 | random_ether_addr(node_id); | 1288 | random_ether_addr(node_id); |