Commit b3feb439 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'usbnet-speed'



Grant Grundler says:

====================
usbnet: speed reporting for devices without MDIO

This series introduces support for USB network devices that report
speed as a part of their protocol, not emulating an MII to be accessed
over MDIO.

v2: rebased on recent upstream changes
v3: incorporated hints on naming and comments
v4: fix misplaced hunks; reword some commit messages;
    add same change for cdc_ether
v4-repost: added "net-next" to subject and Andrew Lunn's Reviewed-by

I'm reposting Oliver Neukum's <oneukum@suse.com> patch series with
fix ups for "misplaced hunks" (landed in the wrong patches).
Please fixup the "author" if "git am" fails to attribute the
patches 1-3 (of 4) to Oliver.

I've tested v4 series with "5.12-rc3+" kernel on Intel NUC6i5SYB
and + Sabrent NT-S25G. Google Pixelbook Go (chromeos-4.4 kernel)
+ Alpha Network AUE2500C were connected directly to the NT-S25G
to get 2.5Gbps link rate:
Settings for enx002427880815:
        Supported ports: [  ]
        Supported link modes:   Not reported
        Supported pause frame use: No
        Supports auto-negotiation: No
        Supported FEC modes: Not reported
        Advertised link modes:  Not reported
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 2500Mb/s
        Duplex: Half
        Auto-negotiation: off
        Port: Twisted Pair
        PHYAD: 0
        Transceiver: internal
        MDI-X: Unknown
        Current message level: 0x00000007 (7)
                               drv probe link
        Link detected: yes

"Duplex" is a lie since we get no information about it.

I expect "Auto-Negotiation" is always true for cdc_ncm and
cdc_ether devices and perhaps someone knows offhand how
to have ethtool report "true" instead.

But this is good step in the right direction.

base-commit: 1c273e10
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e880f8b3 d42ebcbb
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -125,8 +125,8 @@ static const struct ethtool_ops ax88172_ethtool_ops = {
	.get_eeprom		= asix_get_eeprom,
	.set_eeprom		= asix_set_eeprom,
	.nway_reset		= usbnet_nway_reset,
	.get_link_ksettings	= usbnet_get_link_ksettings,
	.set_link_ksettings	= usbnet_set_link_ksettings,
	.get_link_ksettings	= usbnet_get_link_ksettings_mii,
	.set_link_ksettings	= usbnet_set_link_ksettings_mii,
};

static void ax88172_set_multicast(struct net_device *net)
@@ -291,8 +291,8 @@ static const struct ethtool_ops ax88772_ethtool_ops = {
	.get_eeprom		= asix_get_eeprom,
	.set_eeprom		= asix_set_eeprom,
	.nway_reset		= usbnet_nway_reset,
	.get_link_ksettings	= usbnet_get_link_ksettings,
	.set_link_ksettings	= usbnet_set_link_ksettings,
	.get_link_ksettings	= usbnet_get_link_ksettings_mii,
	.set_link_ksettings	= usbnet_set_link_ksettings_mii,
};

static int ax88772_link_reset(struct usbnet *dev)
@@ -782,8 +782,8 @@ static const struct ethtool_ops ax88178_ethtool_ops = {
	.get_eeprom		= asix_get_eeprom,
	.set_eeprom		= asix_set_eeprom,
	.nway_reset		= usbnet_nway_reset,
	.get_link_ksettings	= usbnet_get_link_ksettings,
	.set_link_ksettings	= usbnet_set_link_ksettings,
	.get_link_ksettings	= usbnet_get_link_ksettings_mii,
	.set_link_ksettings	= usbnet_set_link_ksettings_mii,
};

static int marvell_phy_init(struct usbnet *dev)
+20 −7
Original line number Diff line number Diff line
@@ -92,6 +92,18 @@ void usbnet_cdc_update_filter(struct usbnet *dev)
}
EXPORT_SYMBOL_GPL(usbnet_cdc_update_filter);

/* We need to override usbnet_*_link_ksettings in bind() */
static const struct ethtool_ops cdc_ether_ethtool_ops = {
	.get_link		= usbnet_get_link,
	.nway_reset		= usbnet_nway_reset,
	.get_drvinfo		= usbnet_get_drvinfo,
	.get_msglevel		= usbnet_get_msglevel,
	.set_msglevel		= usbnet_set_msglevel,
	.get_ts_info		= ethtool_op_get_ts_info,
	.get_link_ksettings	= usbnet_get_link_ksettings_internal,
	.set_link_ksettings	= NULL,
};

/* probes control interface, claims data interface, collects the bulk
 * endpoints, activates data interface (if needed), maybe sets MTU.
 * all pure cdc, except for certain firmware workarounds, and knowing
@@ -310,6 +322,9 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
		return -ENODEV;
	}

	/* override ethtool_ops */
	dev->net->ethtool_ops = &cdc_ether_ethtool_ops;

	return 0;

bad_desc:
@@ -379,12 +394,10 @@ EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
 * (by Brad Hards) talked with, with more functionality.
 */

static void dumpspeed(struct usbnet *dev, __le32 *speeds)
static void speed_change(struct usbnet *dev, __le32 *speeds)
{
	netif_info(dev, timer, dev->net,
		   "link speeds: %u kbps up, %u kbps down\n",
		   __le32_to_cpu(speeds[0]) / 1000,
		   __le32_to_cpu(speeds[1]) / 1000);
	dev->tx_speed = __le32_to_cpu(speeds[0]);
	dev->rx_speed = __le32_to_cpu(speeds[1]);
}

void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
@@ -396,7 +409,7 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)

	/* SPEED_CHANGE can get split into two 8-byte packets */
	if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
		dumpspeed(dev, (__le32 *) urb->transfer_buffer);
		speed_change(dev, (__le32 *) urb->transfer_buffer);
		return;
	}

@@ -413,7 +426,7 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
		if (urb->actual_length != (sizeof(*event) + 8))
			set_bit(EVENT_STS_SPLIT, &dev->flags);
		else
			dumpspeed(dev, (__le32 *) &event[1]);
			speed_change(dev, (__le32 *) &event[1]);
		break;
	/* USB_CDC_NOTIFY_RESPONSE_AVAILABLE can happen too (e.g. RNDIS),
	 * but there are no standard formats for the response data.
+17 −38
Original line number Diff line number Diff line
@@ -142,8 +142,8 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = {
	.get_sset_count		= cdc_ncm_get_sset_count,
	.get_strings		= cdc_ncm_get_strings,
	.get_ethtool_stats	= cdc_ncm_get_ethtool_stats,
	.get_link_ksettings      = usbnet_get_link_ksettings,
	.set_link_ksettings      = usbnet_set_link_ksettings,
	.get_link_ksettings	= usbnet_get_link_ksettings_internal,
	.set_link_ksettings	= NULL,
};

static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx)
@@ -1825,33 +1825,9 @@ static void
cdc_ncm_speed_change(struct usbnet *dev,
		     struct usb_cdc_speed_change *data)
{
	uint32_t rx_speed = le32_to_cpu(data->DLBitRRate);
	uint32_t tx_speed = le32_to_cpu(data->ULBitRate);

	/* if the speed hasn't changed, don't report it.
	 * RTL8156 shipped before 2021 sends notification about every 32ms.
	 */
	if (dev->rx_speed == rx_speed && dev->tx_speed == tx_speed)
		return;

	dev->rx_speed = rx_speed;
	dev->tx_speed = tx_speed;

	/*
	 * Currently the USB-NET API does not support reporting the actual
	 * device speed. Do print it instead.
	 */
	if ((tx_speed > 1000000) && (rx_speed > 1000000)) {
		netif_info(dev, link, dev->net,
			   "%u mbit/s downlink %u mbit/s uplink\n",
			   (unsigned int)(rx_speed / 1000000U),
			   (unsigned int)(tx_speed / 1000000U));
	} else {
		netif_info(dev, link, dev->net,
			   "%u kbit/s downlink %u kbit/s uplink\n",
			   (unsigned int)(rx_speed / 1000U),
			   (unsigned int)(tx_speed / 1000U));
	}
	/* RTL8156 shipped before 2021 sends notification about every 32ms. */
	dev->rx_speed = le32_to_cpu(data->DLBitRRate);
	dev->tx_speed = le32_to_cpu(data->ULBitRate);
}

static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
@@ -1877,6 +1853,9 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
		 * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be
		 * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE.
		 */
		/* RTL8156 shipped before 2021 sends notification about
		 * every 32ms. Don't forward notification if state is same.
		 */
		if (netif_carrier_ok(dev->net) != !!event->wValue)
			usbnet_link_change(dev, !!event->wValue, 0);
		break;
+2 −2
Original line number Diff line number Diff line
@@ -282,8 +282,8 @@ static const struct ethtool_ops dm9601_ethtool_ops = {
	.get_eeprom_len	= dm9601_get_eeprom_len,
	.get_eeprom	= dm9601_get_eeprom,
	.nway_reset	= usbnet_nway_reset,
	.get_link_ksettings	= usbnet_get_link_ksettings,
	.set_link_ksettings	= usbnet_set_link_ksettings,
	.get_link_ksettings	= usbnet_get_link_ksettings_mii,
	.set_link_ksettings	= usbnet_set_link_ksettings_mii,
};

static void dm9601_set_multicast(struct net_device *net)
+2 −2
Original line number Diff line number Diff line
@@ -452,8 +452,8 @@ static const struct ethtool_ops mcs7830_ethtool_ops = {
	.get_msglevel		= usbnet_get_msglevel,
	.set_msglevel		= usbnet_set_msglevel,
	.nway_reset		= usbnet_nway_reset,
	.get_link_ksettings	= usbnet_get_link_ksettings,
	.set_link_ksettings	= usbnet_set_link_ksettings,
	.get_link_ksettings	= usbnet_get_link_ksettings_mii,
	.set_link_ksettings	= usbnet_set_link_ksettings_mii,
};

static const struct net_device_ops mcs7830_netdev_ops = {
Loading