The old method for reporting network speed upwards assumed that a device uses MDIO and uses the generic phy functions based on that. Add a a primitive internal version not making the assumption reporting back directly what the status operations record. v2: adjusted to recent changes Signed-off-by: Oliver Neukum <oneukum@xxxxxxxx> Tested-by: Roland Dreier <roland@xxxxxxxxxx> --- drivers/net/usb/usbnet.c | 23 +++++++++++++++++++++++ include/linux/usb/usbnet.h | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index e2ca88259b05..6f8fcc276ca7 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -961,6 +961,27 @@ int usbnet_get_link_ksettings_mdio(struct net_device *net, } EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_mdio); +int usbnet_get_link_ksettings_internal(struct net_device *net, + struct ethtool_link_ksettings *cmd) +{ + struct usbnet *dev = netdev_priv(net); + + /* the assumption that speed is equal on tx and rx + * is deeply engrained into the networking layer. + * For wireless stuff it is not true. + * We assume that rxspeed matters more. + */ + if (dev->rxspeed != SPEED_UNKNOWN) + cmd->base.speed = dev->rxspeed / 1000000; + else if (dev->txspeed != SPEED_UNKNOWN) + cmd->base.speed = dev->txspeed / 1000000; + else + cmd->base.speed = SPEED_UNKNOWN; + + return 0; +} +EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_internal); + int usbnet_set_link_ksettings_mdio(struct net_device *net, const struct ethtool_link_ksettings *cmd) { @@ -1664,6 +1685,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->intf = udev; dev->driver_info = info; dev->driver_name = name; + dev->rxspeed = SPEED_UNKNOWN; /* unknown or handled by MII */ + dev->txspeed = SPEED_UNKNOWN; net->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); if (!net->tstats) diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index fd65b7a5ee15..a91c6defb104 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -53,6 +53,8 @@ struct usbnet { u32 hard_mtu; /* count any extra framing */ size_t rx_urb_size; /* size for rx urbs */ struct mii_if_info mii; + long rxspeed; /* if MII is not used */ + long txspeed; /* if MII is not used */ /* various kinds of pending driver work */ struct sk_buff_head rxq; @@ -269,6 +271,8 @@ extern void usbnet_purge_paused_rxq(struct usbnet *); extern int usbnet_get_link_ksettings_mdio(struct net_device *net, struct ethtool_link_ksettings *cmd); +extern int usbnet_get_link_ksettings_internal(struct net_device *net, + struct ethtool_link_ksettings *cmd); extern int usbnet_set_link_ksettings_mdio(struct net_device *net, const struct ethtool_link_ksettings *cmd); extern u32 usbnet_get_link(struct net_device *net); -- 2.26.2