Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usbnet: add method for reporting speed without MII

The old method for reporting link speed assumed a driver uses the
generic phy (mii) MDIO read/write functions. CDC devices don't
expose the phy.

Add a primitive internal version reporting back directly what
the CDC notification/status operations recorded.

v2: rebased on upstream
v3: changed names and made clear which units are used
v4: moved hunks to correct patch; rewrote commmit messages

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Tested-by: Roland Dreier <roland@kernel.org>
Reviewed-by: Grant Grundler <grundler@chromium.org>
Tested-by: Grant Grundler <grundler@chromium.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Oliver Neukum and committed by
David S. Miller
956baa99 77651900

+28 -2
+23
drivers/net/usb/usbnet.c
··· 961 961 } 962 962 EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_mii); 963 963 964 + int usbnet_get_link_ksettings_internal(struct net_device *net, 965 + struct ethtool_link_ksettings *cmd) 966 + { 967 + struct usbnet *dev = netdev_priv(net); 968 + 969 + /* the assumption that speed is equal on tx and rx 970 + * is deeply engrained into the networking layer. 971 + * For wireless stuff it is not true. 972 + * We assume that rx_speed matters more. 973 + */ 974 + if (dev->rx_speed != SPEED_UNSET) 975 + cmd->base.speed = dev->rx_speed / 1000000; 976 + else if (dev->tx_speed != SPEED_UNSET) 977 + cmd->base.speed = dev->tx_speed / 1000000; 978 + else 979 + cmd->base.speed = SPEED_UNKNOWN; 980 + 981 + return 0; 982 + } 983 + EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_internal); 984 + 964 985 int usbnet_set_link_ksettings_mii(struct net_device *net, 965 986 const struct ethtool_link_ksettings *cmd) 966 987 { ··· 1685 1664 dev->intf = udev; 1686 1665 dev->driver_info = info; 1687 1666 dev->driver_name = name; 1667 + dev->rx_speed = SPEED_UNSET; 1668 + dev->tx_speed = SPEED_UNSET; 1688 1669 1689 1670 net->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 1690 1671 if (!net->tstats)
+5 -2
include/linux/usb/usbnet.h
··· 53 53 u32 hard_mtu; /* count any extra framing */ 54 54 size_t rx_urb_size; /* size for rx urbs */ 55 55 struct mii_if_info mii; 56 + long rx_speed; /* If MII not used */ 57 + long tx_speed; /* If MII not used */ 58 + # define SPEED_UNSET -1 56 59 57 60 /* various kinds of pending driver work */ 58 61 struct sk_buff_head rxq; ··· 84 81 # define EVENT_LINK_CHANGE 11 85 82 # define EVENT_SET_RX_MODE 12 86 83 # define EVENT_NO_IP_ALIGN 13 87 - u32 rx_speed; /* in bps - NOT Mbps */ 88 - u32 tx_speed; /* in bps - NOT Mbps */ 89 84 }; 90 85 91 86 static inline struct usb_driver *driver_of(struct usb_interface *intf) ··· 272 271 struct ethtool_link_ksettings *cmd); 273 272 extern int usbnet_set_link_ksettings_mii(struct net_device *net, 274 273 const struct ethtool_link_ksettings *cmd); 274 + extern int usbnet_get_link_ksettings_internal(struct net_device *net, 275 + struct ethtool_link_ksettings *cmd); 275 276 extern u32 usbnet_get_link(struct net_device *net); 276 277 extern u32 usbnet_get_msglevel(struct net_device *); 277 278 extern void usbnet_set_msglevel(struct net_device *, u32);