Commit 956baa99 authored by Oliver Neukum's avatar Oliver Neukum Committed by David S. Miller
Browse files

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: default avatarOliver Neukum <oneukum@suse.com>
Tested-by: default avatarRoland Dreier <roland@kernel.org>
Reviewed-by: default avatarGrant Grundler <grundler@chromium.org>
Tested-by: default avatarGrant Grundler <grundler@chromium.org>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 77651900
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -961,6 +961,27 @@ int usbnet_get_link_ksettings_mii(struct net_device *net,
}
EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_mii);

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 rx_speed matters more.
	 */
	if (dev->rx_speed != SPEED_UNSET)
		cmd->base.speed = dev->rx_speed / 1000000;
	else if (dev->tx_speed != SPEED_UNSET)
		cmd->base.speed = dev->tx_speed / 1000000;
	else
		cmd->base.speed = SPEED_UNKNOWN;

	return 0;
}
EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_internal);

int usbnet_set_link_ksettings_mii(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->rx_speed = SPEED_UNSET;
	dev->tx_speed = SPEED_UNSET;

	net->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
	if (!net->tstats)
+5 −2
Original line number Diff line number Diff line
@@ -53,6 +53,9 @@ struct usbnet {
	u32			hard_mtu;	/* count any extra framing */
	size_t			rx_urb_size;	/* size for rx urbs */
	struct mii_if_info	mii;
	long			rx_speed;	/* If MII not used */
	long			tx_speed;	/* If MII not used */
#		define SPEED_UNSET	-1

	/* various kinds of pending driver work */
	struct sk_buff_head	rxq;
@@ -81,8 +84,6 @@ struct usbnet {
#		define EVENT_LINK_CHANGE	11
#		define EVENT_SET_RX_MODE	12
#		define EVENT_NO_IP_ALIGN	13
	u32			rx_speed;	/* in bps - NOT Mbps */
	u32			tx_speed;	/* in bps - NOT Mbps */
};

static inline struct usb_driver *driver_of(struct usb_interface *intf)
@@ -271,6 +272,8 @@ extern int usbnet_get_link_ksettings_mii(struct net_device *net,
				     struct ethtool_link_ksettings *cmd);
extern int usbnet_set_link_ksettings_mii(struct net_device *net,
				     const struct ethtool_link_ksettings *cmd);
extern int usbnet_get_link_ksettings_internal(struct net_device *net,
				     struct ethtool_link_ksettings *cmd);
extern u32 usbnet_get_link(struct net_device *net);
extern u32 usbnet_get_msglevel(struct net_device *);
extern void usbnet_set_msglevel(struct net_device *, u32);