On Fri, 2009-01-02 at 01:04 +0000, Reuben Thomas wrote: > On Fri, 26 Dec 2008, Moritz Muehlenhoff wrote: > > > On Sun, Sep 30, 2007 at 12:41:35AM +0100, Reuben Thomas wrote: > >> On Sun, 30 Sep 2007, Michael Biebl wrote: > >> > >>> Please reassign to the package providing the flusb driver. In your case > >>> that should probably be on of the linux-image-* packages. > >> > >> Sounds like the right package, the kernel modules involved seem to be > >> rather usbnet, plusb and asix...). > > > > Does this error still occur with more recent kernel versions? > > If I try the command indicated further up the thread, that is, > > $ cat `find . -name carrier | grep usb0` > > I get the following output: > > cat: ./devices/pci0000:00/0000:00:1d.7/usb5/5-6/5-6.2/5-6.2.1/5-6.2.1:1.0/net/usb0/carrier: Invalid argument > > I don't know what this indicates; I hope you do! > > # ls -l carrier > -r--r--r-- 1 root root 4096 2009-01-02 01:00 carrier It means you need to bring the interface up before you can find out the link state. In any case, I think this is still broken - Network Manager will use the ethtool get_link() operation, which the generic usbnet driver implements even where the hardware-specific driver cannot detect the link state. Please could you test the attached patch against Linux 2.6.30? The Debian kernel handbook explains how to do this: <http://kernel-handbook.alioth.debian.org/ch-common-tasks.html#s-common-official>. I can also prepare a patch against Linux 2.6.26 if you want. Ben. -- Ben Hutchings Who are all these weirdos? - David Bowie, about L-Space IRC channel #afp
From 3b051716486432b2967db5b96439234dd3dd7849 Mon Sep 17 00:00:00 2001
From: Ben Hutchings <ben@decadent.org.uk>
Date: Tue, 8 Sep 2009 23:01:02 +0100
Subject: [PATCH] usbnet: Do not implement ethtool get_link() if link state is unknown
Many USB network drivers cannot detect the link state. Only define
the ethtool get_link() operation for those that implement
check_connect() or set a flag to indicate that link state is
available through MII or netif_carrier_ok().
---
drivers/net/usb/asix.c | 12 ++++++------
drivers/net/usb/cdc_ether.c | 2 +-
drivers/net/usb/mcs7830.c | 4 ++--
drivers/net/usb/smsc95xx.c | 2 +-
drivers/net/usb/usbnet.c | 17 +++++++++++++++--
include/linux/usb/usbnet.h | 2 ++
6 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 87b4a02..b062376 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -1327,7 +1327,7 @@ static const struct driver_info ax8817x_info = {
.status = asix_status,
.link_reset = ax88172_link_reset,
.reset = ax88172_link_reset,
- .flags = FLAG_ETHER,
+ .flags = FLAG_ETHER | FLAG_GET_LINK,
.data = 0x00130103,
};
@@ -1337,7 +1337,7 @@ static const struct driver_info dlink_dub_e100_info = {
.status = asix_status,
.link_reset = ax88172_link_reset,
.reset = ax88172_link_reset,
- .flags = FLAG_ETHER,
+ .flags = FLAG_ETHER | FLAG_GET_LINK,
.data = 0x009f9d9f,
};
@@ -1347,7 +1347,7 @@ static const struct driver_info netgear_fa120_info = {
.status = asix_status,
.link_reset = ax88172_link_reset,
.reset = ax88172_link_reset,
- .flags = FLAG_ETHER,
+ .flags = FLAG_ETHER | FLAG_GET_LINK,
.data = 0x00130103,
};
@@ -1357,7 +1357,7 @@ static const struct driver_info hawking_uf200_info = {
.status = asix_status,
.link_reset = ax88172_link_reset,
.reset = ax88172_link_reset,
- .flags = FLAG_ETHER,
+ .flags = FLAG_ETHER | FLAG_GET_LINK,
.data = 0x001f1d1f,
};
@@ -1367,7 +1367,7 @@ static const struct driver_info ax88772_info = {
.status = asix_status,
.link_reset = ax88772_link_reset,
.reset = ax88772_link_reset,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_GET_LINK,
.rx_fixup = asix_rx_fixup,
.tx_fixup = asix_tx_fixup,
};
@@ -1378,7 +1378,7 @@ static const struct driver_info ax88178_info = {
.status = asix_status,
.link_reset = ax88178_link_reset,
.reset = ax88178_link_reset,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_GET_LINK,
.rx_fixup = asix_rx_fixup,
.tx_fixup = asix_tx_fixup,
};
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 55e8ecc..dfaea39 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -444,7 +444,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
static const struct driver_info cdc_info = {
.description = "CDC Ethernet Device",
- .flags = FLAG_ETHER,
+ .flags = FLAG_ETHER | FLAG_GET_LINK,
// .check_connect = cdc_check_connect,
.bind = cdc_bind,
.unbind = usbnet_cdc_unbind,
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 7ae9afe..ccef9ca 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -549,7 +549,7 @@ static const struct driver_info moschip_info = {
.description = "MOSCHIP 7830/7730 usb-NET adapter",
.bind = mcs7830_bind,
.rx_fixup = mcs7830_rx_fixup,
- .flags = FLAG_ETHER,
+ .flags = FLAG_ETHER | FLAG_GET_LINK,
.in = 1,
.out = 2,
};
@@ -558,7 +558,7 @@ static const struct driver_info sitecom_info = {
.description = "Sitecom LN-30 usb-NET adapter",
.bind = mcs7830_bind,
.rx_fixup = mcs7830_rx_fixup,
- .flags = FLAG_ETHER,
+ .flags = FLAG_ETHER | FLAG_GET_LINK,
.in = 1,
.out = 2,
};
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 5a72833..bea78d1 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1232,7 +1232,7 @@ static const struct driver_info smsc95xx_info = {
.rx_fixup = smsc95xx_rx_fixup,
.tx_fixup = smsc95xx_tx_fixup,
.status = smsc95xx_status,
- .flags = FLAG_ETHER,
+ .flags = FLAG_ETHER | FLAG_GET_LINK,
};
static const struct usb_device_id products[] = {
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index f3a2fce..5ae11c7 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -763,7 +763,7 @@ void usbnet_set_msglevel (struct net_device *net, u32 level)
EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
/* drivers may override default ethtool_ops in their bind() routine */
-static struct ethtool_ops usbnet_ethtool_ops = {
+static struct ethtool_ops usbnet_get_link_ethtool_ops = {
.get_settings = usbnet_get_settings,
.set_settings = usbnet_set_settings,
.get_link = usbnet_get_link,
@@ -773,6 +773,15 @@ static struct ethtool_ops usbnet_ethtool_ops = {
.set_msglevel = usbnet_set_msglevel,
};
+static struct ethtool_ops usbnet_ethtool_ops = {
+ .get_settings = usbnet_get_settings,
+ .set_settings = usbnet_set_settings,
+ .nway_reset = usbnet_nway_reset,
+ .get_drvinfo = usbnet_get_drvinfo,
+ .get_msglevel = usbnet_get_msglevel,
+ .set_msglevel = usbnet_set_msglevel,
+};
+
/*-------------------------------------------------------------------------*/
/* work that cannot be done in interrupt context uses keventd.
@@ -1192,7 +1201,11 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
net->tx_timeout = usbnet_tx_timeout;
#endif
net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
- net->ethtool_ops = &usbnet_ethtool_ops;
+ if (dev->driver_info->check_connect ||
+ dev->driver_info->flags & FLAG_GET_LINK)
+ net->ethtool_ops = &usbnet_get_link_ethtool_ops;
+ else
+ net->ethtool_ops = &usbnet_ethtool_ops;
// allow device-specific bind/init procedures
// NOTE net->name still not usable ...
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 36fabb9..45f783e 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -88,6 +88,8 @@ struct driver_info {
#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
#define FLAG_WLAN 0x0080 /* use "wlan%d" names */
+#define FLAG_GET_LINK 0x0100 /* link state is available through
+ * MII or netif_carrier_ok() */
/* init device ... can sleep, or cause probe() failure */
int (*bind)(struct usbnet *, struct usb_interface *);
--
1.6.3.3
Attachment:
signature.asc
Description: This is a digitally signed message part