Commit eb47c274 authored by Oliver Neukum's avatar Oliver Neukum Committed by David S. Miller

net: cdc_ncm: record speed in status method

Until very recently, the usbnet framework only had support functions
for devices which reported the link speed by explicitly querying the
PHY over a MDIO interface. However, the cdc_ncm devices send
notifications when the link state or link speeds change and do not
expose the PHY (or modem) directly.

Support funtions (e.g. usbnet_get_link_ksettings_internal()) to directly
query state recorded by the cdc_ncm driver were added in a previous patch.

So instead of cdc_ncm spewing the link speed into the dmesg buffer,
record the link speed encoded in these notifications and tell the
usbnet framework to use the new functions to get link speed/state.
Link speed/state is now available via ethtool.

This is especially useful given all current RTL8156 devices emit
a connection/speed status notification every 32ms and this would
fill the dmesg buffer. This implementation replaces the one
recently submitted in de658a19 :
   "net: usb: cdc_ncm: don't spew notifications"

v2: rebased on upstream
v3: changed variable names
v4: rewrote commit message
Signed-off-by: default avatarOliver Neukum <oneukum@suse.com>
Tested-by: default avatarRoland Dreier <roland@kernel.org>
Signed-off-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 956baa99
...@@ -142,8 +142,8 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = { ...@@ -142,8 +142,8 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = {
.get_sset_count = cdc_ncm_get_sset_count, .get_sset_count = cdc_ncm_get_sset_count,
.get_strings = cdc_ncm_get_strings, .get_strings = cdc_ncm_get_strings,
.get_ethtool_stats = cdc_ncm_get_ethtool_stats, .get_ethtool_stats = cdc_ncm_get_ethtool_stats,
.get_link_ksettings = usbnet_get_link_ksettings_mii, .get_link_ksettings = usbnet_get_link_ksettings_internal,
.set_link_ksettings = usbnet_set_link_ksettings_mii, .set_link_ksettings = NULL,
}; };
static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx) static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx)
...@@ -1825,33 +1825,9 @@ static void ...@@ -1825,33 +1825,9 @@ static void
cdc_ncm_speed_change(struct usbnet *dev, cdc_ncm_speed_change(struct usbnet *dev,
struct usb_cdc_speed_change *data) struct usb_cdc_speed_change *data)
{ {
uint32_t rx_speed = le32_to_cpu(data->DLBitRRate); /* RTL8156 shipped before 2021 sends notification about every 32ms. */
uint32_t tx_speed = le32_to_cpu(data->ULBitRate); dev->rx_speed = le32_to_cpu(data->DLBitRRate);
dev->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));
}
} }
static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) 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) ...@@ -1877,6 +1853,9 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
* USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be
* sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. * 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) if (netif_carrier_ok(dev->net) != !!event->wValue)
usbnet_link_change(dev, !!event->wValue, 0); usbnet_link_change(dev, !!event->wValue, 0);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment