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

Configure Feed

Select the types of activity you want to include in your feed.

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: 1c273e10bc0cc7efb933e0ca10e260cdfc9f0b8c
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+94 -73
+6 -6
drivers/net/usb/asix_devices.c
··· 125 125 .get_eeprom = asix_get_eeprom, 126 126 .set_eeprom = asix_set_eeprom, 127 127 .nway_reset = usbnet_nway_reset, 128 - .get_link_ksettings = usbnet_get_link_ksettings, 129 - .set_link_ksettings = usbnet_set_link_ksettings, 128 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 129 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 130 130 }; 131 131 132 132 static void ax88172_set_multicast(struct net_device *net) ··· 291 291 .get_eeprom = asix_get_eeprom, 292 292 .set_eeprom = asix_set_eeprom, 293 293 .nway_reset = usbnet_nway_reset, 294 - .get_link_ksettings = usbnet_get_link_ksettings, 295 - .set_link_ksettings = usbnet_set_link_ksettings, 294 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 295 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 296 296 }; 297 297 298 298 static int ax88772_link_reset(struct usbnet *dev) ··· 782 782 .get_eeprom = asix_get_eeprom, 783 783 .set_eeprom = asix_set_eeprom, 784 784 .nway_reset = usbnet_nway_reset, 785 - .get_link_ksettings = usbnet_get_link_ksettings, 786 - .set_link_ksettings = usbnet_set_link_ksettings, 785 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 786 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 787 787 }; 788 788 789 789 static int marvell_phy_init(struct usbnet *dev)
+20 -7
drivers/net/usb/cdc_ether.c
··· 92 92 } 93 93 EXPORT_SYMBOL_GPL(usbnet_cdc_update_filter); 94 94 95 + /* We need to override usbnet_*_link_ksettings in bind() */ 96 + static const struct ethtool_ops cdc_ether_ethtool_ops = { 97 + .get_link = usbnet_get_link, 98 + .nway_reset = usbnet_nway_reset, 99 + .get_drvinfo = usbnet_get_drvinfo, 100 + .get_msglevel = usbnet_get_msglevel, 101 + .set_msglevel = usbnet_set_msglevel, 102 + .get_ts_info = ethtool_op_get_ts_info, 103 + .get_link_ksettings = usbnet_get_link_ksettings_internal, 104 + .set_link_ksettings = NULL, 105 + }; 106 + 95 107 /* probes control interface, claims data interface, collects the bulk 96 108 * endpoints, activates data interface (if needed), maybe sets MTU. 97 109 * all pure cdc, except for certain firmware workarounds, and knowing ··· 322 310 return -ENODEV; 323 311 } 324 312 313 + /* override ethtool_ops */ 314 + dev->net->ethtool_ops = &cdc_ether_ethtool_ops; 315 + 325 316 return 0; 326 317 327 318 bad_desc: ··· 394 379 * (by Brad Hards) talked with, with more functionality. 395 380 */ 396 381 397 - static void dumpspeed(struct usbnet *dev, __le32 *speeds) 382 + static void speed_change(struct usbnet *dev, __le32 *speeds) 398 383 { 399 - netif_info(dev, timer, dev->net, 400 - "link speeds: %u kbps up, %u kbps down\n", 401 - __le32_to_cpu(speeds[0]) / 1000, 402 - __le32_to_cpu(speeds[1]) / 1000); 384 + dev->tx_speed = __le32_to_cpu(speeds[0]); 385 + dev->rx_speed = __le32_to_cpu(speeds[1]); 403 386 } 404 387 405 388 void usbnet_cdc_status(struct usbnet *dev, struct urb *urb) ··· 409 396 410 397 /* SPEED_CHANGE can get split into two 8-byte packets */ 411 398 if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) { 412 - dumpspeed(dev, (__le32 *) urb->transfer_buffer); 399 + speed_change(dev, (__le32 *) urb->transfer_buffer); 413 400 return; 414 401 } 415 402 ··· 426 413 if (urb->actual_length != (sizeof(*event) + 8)) 427 414 set_bit(EVENT_STS_SPLIT, &dev->flags); 428 415 else 429 - dumpspeed(dev, (__le32 *) &event[1]); 416 + speed_change(dev, (__le32 *) &event[1]); 430 417 break; 431 418 /* USB_CDC_NOTIFY_RESPONSE_AVAILABLE can happen too (e.g. RNDIS), 432 419 * but there are no standard formats for the response data.
+17 -38
drivers/net/usb/cdc_ncm.c
··· 133 133 static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx); 134 134 135 135 static const struct ethtool_ops cdc_ncm_ethtool_ops = { 136 - .get_link = usbnet_get_link, 137 - .nway_reset = usbnet_nway_reset, 138 - .get_drvinfo = usbnet_get_drvinfo, 139 - .get_msglevel = usbnet_get_msglevel, 140 - .set_msglevel = usbnet_set_msglevel, 141 - .get_ts_info = ethtool_op_get_ts_info, 142 - .get_sset_count = cdc_ncm_get_sset_count, 143 - .get_strings = cdc_ncm_get_strings, 144 - .get_ethtool_stats = cdc_ncm_get_ethtool_stats, 145 - .get_link_ksettings = usbnet_get_link_ksettings, 146 - .set_link_ksettings = usbnet_set_link_ksettings, 136 + .get_link = usbnet_get_link, 137 + .nway_reset = usbnet_nway_reset, 138 + .get_drvinfo = usbnet_get_drvinfo, 139 + .get_msglevel = usbnet_get_msglevel, 140 + .set_msglevel = usbnet_set_msglevel, 141 + .get_ts_info = ethtool_op_get_ts_info, 142 + .get_sset_count = cdc_ncm_get_sset_count, 143 + .get_strings = cdc_ncm_get_strings, 144 + .get_ethtool_stats = cdc_ncm_get_ethtool_stats, 145 + .get_link_ksettings = usbnet_get_link_ksettings_internal, 146 + .set_link_ksettings = NULL, 147 147 }; 148 148 149 149 static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx) ··· 1825 1825 cdc_ncm_speed_change(struct usbnet *dev, 1826 1826 struct usb_cdc_speed_change *data) 1827 1827 { 1828 - uint32_t rx_speed = le32_to_cpu(data->DLBitRRate); 1829 - uint32_t tx_speed = le32_to_cpu(data->ULBitRate); 1830 - 1831 - /* if the speed hasn't changed, don't report it. 1832 - * RTL8156 shipped before 2021 sends notification about every 32ms. 1833 - */ 1834 - if (dev->rx_speed == rx_speed && dev->tx_speed == tx_speed) 1835 - return; 1836 - 1837 - dev->rx_speed = rx_speed; 1838 - dev->tx_speed = tx_speed; 1839 - 1840 - /* 1841 - * Currently the USB-NET API does not support reporting the actual 1842 - * device speed. Do print it instead. 1843 - */ 1844 - if ((tx_speed > 1000000) && (rx_speed > 1000000)) { 1845 - netif_info(dev, link, dev->net, 1846 - "%u mbit/s downlink %u mbit/s uplink\n", 1847 - (unsigned int)(rx_speed / 1000000U), 1848 - (unsigned int)(tx_speed / 1000000U)); 1849 - } else { 1850 - netif_info(dev, link, dev->net, 1851 - "%u kbit/s downlink %u kbit/s uplink\n", 1852 - (unsigned int)(rx_speed / 1000U), 1853 - (unsigned int)(tx_speed / 1000U)); 1854 - } 1828 + /* RTL8156 shipped before 2021 sends notification about every 32ms. */ 1829 + dev->rx_speed = le32_to_cpu(data->DLBitRRate); 1830 + dev->tx_speed = le32_to_cpu(data->ULBitRate); 1855 1831 } 1856 1832 1857 1833 static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) ··· 1852 1876 * According to the CDC NCM specification ch.7.1 1853 1877 * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be 1854 1878 * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. 1879 + */ 1880 + /* RTL8156 shipped before 2021 sends notification about 1881 + * every 32ms. Don't forward notification if state is same. 1855 1882 */ 1856 1883 if (netif_carrier_ok(dev->net) != !!event->wValue) 1857 1884 usbnet_link_change(dev, !!event->wValue, 0);
+2 -2
drivers/net/usb/dm9601.c
··· 282 282 .get_eeprom_len = dm9601_get_eeprom_len, 283 283 .get_eeprom = dm9601_get_eeprom, 284 284 .nway_reset = usbnet_nway_reset, 285 - .get_link_ksettings = usbnet_get_link_ksettings, 286 - .set_link_ksettings = usbnet_set_link_ksettings, 285 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 286 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 287 287 }; 288 288 289 289 static void dm9601_set_multicast(struct net_device *net)
+2 -2
drivers/net/usb/mcs7830.c
··· 452 452 .get_msglevel = usbnet_get_msglevel, 453 453 .set_msglevel = usbnet_set_msglevel, 454 454 .nway_reset = usbnet_nway_reset, 455 - .get_link_ksettings = usbnet_get_link_ksettings, 456 - .set_link_ksettings = usbnet_set_link_ksettings, 455 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 456 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 457 457 }; 458 458 459 459 static const struct net_device_ops mcs7830_netdev_ops = {
+2 -2
drivers/net/usb/sierra_net.c
··· 629 629 .get_msglevel = usbnet_get_msglevel, 630 630 .set_msglevel = usbnet_set_msglevel, 631 631 .nway_reset = usbnet_nway_reset, 632 - .get_link_ksettings = usbnet_get_link_ksettings, 633 - .set_link_ksettings = usbnet_set_link_ksettings, 632 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 633 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 634 634 }; 635 635 636 636 static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
+2 -2
drivers/net/usb/smsc75xx.c
··· 741 741 .set_eeprom = smsc75xx_ethtool_set_eeprom, 742 742 .get_wol = smsc75xx_ethtool_get_wol, 743 743 .set_wol = smsc75xx_ethtool_set_wol, 744 - .get_link_ksettings = usbnet_get_link_ksettings, 745 - .set_link_ksettings = usbnet_set_link_ksettings, 744 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 745 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 746 746 }; 747 747 748 748 static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+2 -2
drivers/net/usb/sr9700.c
··· 250 250 .get_eeprom_len = sr9700_get_eeprom_len, 251 251 .get_eeprom = sr9700_get_eeprom, 252 252 .nway_reset = usbnet_nway_reset, 253 - .get_link_ksettings = usbnet_get_link_ksettings, 254 - .set_link_ksettings = usbnet_set_link_ksettings, 253 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 254 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 255 255 }; 256 256 257 257 static void sr9700_set_multicast(struct net_device *netdev)
+2 -2
drivers/net/usb/sr9800.c
··· 527 527 .get_eeprom_len = sr_get_eeprom_len, 528 528 .get_eeprom = sr_get_eeprom, 529 529 .nway_reset = usbnet_nway_reset, 530 - .get_link_ksettings = usbnet_get_link_ksettings, 531 - .set_link_ksettings = usbnet_set_link_ksettings, 530 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 531 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 532 532 }; 533 533 534 534 static int sr9800_link_reset(struct usbnet *dev)
+32 -6
drivers/net/usb/usbnet.c
··· 944 944 * they'll probably want to use this base set. 945 945 */ 946 946 947 - int usbnet_get_link_ksettings(struct net_device *net, 947 + /* These methods are written on the assumption that the device 948 + * uses MII 949 + */ 950 + int usbnet_get_link_ksettings_mii(struct net_device *net, 948 951 struct ethtool_link_ksettings *cmd) 949 952 { 950 953 struct usbnet *dev = netdev_priv(net); ··· 959 956 960 957 return 0; 961 958 } 962 - EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings); 959 + EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_mii); 963 960 964 - int usbnet_set_link_ksettings(struct net_device *net, 961 + int usbnet_get_link_ksettings_internal(struct net_device *net, 962 + struct ethtool_link_ksettings *cmd) 963 + { 964 + struct usbnet *dev = netdev_priv(net); 965 + 966 + /* the assumption that speed is equal on tx and rx 967 + * is deeply engrained into the networking layer. 968 + * For wireless stuff it is not true. 969 + * We assume that rx_speed matters more. 970 + */ 971 + if (dev->rx_speed != SPEED_UNSET) 972 + cmd->base.speed = dev->rx_speed / 1000000; 973 + else if (dev->tx_speed != SPEED_UNSET) 974 + cmd->base.speed = dev->tx_speed / 1000000; 975 + else 976 + cmd->base.speed = SPEED_UNKNOWN; 977 + 978 + return 0; 979 + } 980 + EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_internal); 981 + 982 + int usbnet_set_link_ksettings_mii(struct net_device *net, 965 983 const struct ethtool_link_ksettings *cmd) 966 984 { 967 985 struct usbnet *dev = netdev_priv(net); ··· 1002 978 1003 979 return retval; 1004 980 } 1005 - EXPORT_SYMBOL_GPL(usbnet_set_link_ksettings); 981 + EXPORT_SYMBOL_GPL(usbnet_set_link_ksettings_mii); 1006 982 1007 983 u32 usbnet_get_link (struct net_device *net) 1008 984 { ··· 1067 1043 .get_msglevel = usbnet_get_msglevel, 1068 1044 .set_msglevel = usbnet_set_msglevel, 1069 1045 .get_ts_info = ethtool_op_get_ts_info, 1070 - .get_link_ksettings = usbnet_get_link_ksettings, 1071 - .set_link_ksettings = usbnet_set_link_ksettings, 1046 + .get_link_ksettings = usbnet_get_link_ksettings_mii, 1047 + .set_link_ksettings = usbnet_set_link_ksettings_mii, 1072 1048 }; 1073 1049 1074 1050 /*-------------------------------------------------------------------------*/ ··· 1685 1661 dev->intf = udev; 1686 1662 dev->driver_info = info; 1687 1663 dev->driver_name = name; 1664 + dev->rx_speed = SPEED_UNSET; 1665 + dev->tx_speed = SPEED_UNSET; 1688 1666 1689 1667 net->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 1690 1668 if (!net->tstats)
+7 -4
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) ··· 268 267 extern void usbnet_resume_rx(struct usbnet *); 269 268 extern void usbnet_purge_paused_rxq(struct usbnet *); 270 269 271 - extern int usbnet_get_link_ksettings(struct net_device *net, 270 + extern int usbnet_get_link_ksettings_mii(struct net_device *net, 272 271 struct ethtool_link_ksettings *cmd); 273 - extern int usbnet_set_link_ksettings(struct net_device *net, 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);