diff mbox series

[2/3] usbnet: add method for reporting speed without MDIO

Message ID 20210107113518.21322-3-oneukum@suse.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series [1/3] usbnet: specify naming of usbnet_set/get_link_ksettings | expand

Checks

Context Check Description
netdev/cover_letter warning Series does not have a cover letter
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Guessed tree name to be net-next
netdev/subject_prefix warning Target tree name not specified in the subject
netdev/cc_maintainers warning 3 maintainers not CCed: kuba@kernel.org linux-usb@vger.kernel.org gregkh@linuxfoundation.org
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 40 this patch: 40
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch warning CHECK: Alignment should match open parenthesis CHECK: extern prototypes should be avoided in .h files
netdev/build_allmodconfig_warn success Errors and warnings before: 39 this patch: 39
netdev/header_inline success Link
netdev/stable success Stable not CCed

Commit Message

Oliver Neukum Jan. 7, 2021, 11:35 a.m. UTC
The old method for reporting network speed upwards
assumed that a device uses MDIO and uses the generic phy
functions based on that.
Add a a primitive internal version not making the assumption
reporting back directly what the status operations record.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Tested-by: Roland Dreier <roland@kernel.org>
---
 drivers/net/usb/usbnet.c   | 23 +++++++++++++++++++++++
 include/linux/usb/usbnet.h |  4 ++++
 2 files changed, 27 insertions(+)

Comments

Andrew Lunn Jan. 7, 2021, 7:27 p.m. UTC | #1
On Thu, Jan 07, 2021 at 12:35:17PM +0100, Oliver Neukum wrote:

Hi Oliver

> +++ b/include/linux/usb/usbnet.h
> @@ -53,6 +53,8 @@ struct usbnet {
>  	u32			hard_mtu;	/* count any extra framing */
>  	size_t			rx_urb_size;	/* size for rx urbs */
>  	struct mii_if_info	mii;
> +	long			rxspeed;	/* if MII is not used */
> +	long			txspeed;	/* if MII is not used */

How generic is this really? I don't know USB networking, so i cannot
say for myself.

I'm wondering if these should be added to cdc_ncm_ctx, and
usbnet_get_link_ksettings_ncm function should be added?

Having said that, USB_CDC_NOTIFY_SPEED_CHANGE seems like it could also
use this. Should the patch set also handle that notification and set
usbnet->rxspeed and usbnet->txspeed? These would then be used in
multiple places and that would justify it being in struct usbnet.

       Andrew
Oliver Neukum Jan. 11, 2021, 12:07 p.m. UTC | #2
Am Donnerstag, den 07.01.2021, 20:27 +0100 schrieb Andrew Lunn:
> On Thu, Jan 07, 2021 at 12:35:17PM +0100, Oliver Neukum wrote:
> 
> Hi Oliver
> 
> > +++ b/include/linux/usb/usbnet.h
> > @@ -53,6 +53,8 @@ struct usbnet {
> >  	u32			hard_mtu;	/* count any extra framing */
> >  	size_t			rx_urb_size;	/* size for rx urbs */
> >  	struct mii_if_info	mii;
> > +	long			rxspeed;	/* if MII is not used */
> > +	long			txspeed;	/* if MII is not used */
> 
> How generic is this really? I don't know USB networking, so i cannot
> say for myself.
> 
> I'm wondering if these should be added to cdc_ncm_ctx, and
> usbnet_get_link_ksettings_ncm function should be added?
> 
> Having said that, USB_CDC_NOTIFY_SPEED_CHANGE seems like it could also
> use this. Should the patch set also handle that notification and set
> usbnet->rxspeed and usbnet->txspeed? These would then be used in
> multiple places and that would justify it being in struct usbnet.

Hi,

yes, everything that gets notification in CDC style should use this
mechanism.

	Regards
		Oliver
diff mbox series

Patch

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index e2ca88259b05..fe702ef32007 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -961,6 +961,27 @@  int usbnet_get_link_ksettings_mdio(struct net_device *net,
 }
 EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_mdio);
 
+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 rxspeed matters more.
+	 */
+	if (dev->rxspeed != -1)
+		cmd->base.speed = dev->rxspeed / 1000000;
+	else if (dev->txspeed != -1)
+		cmd->base.speed = dev->txspeed / 1000000;
+	else
+		cmd->base.speed = SPEED_UNKNOWN;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(usbnet_get_link_ksettings_internal);
+
 int usbnet_set_link_ksettings_mdio(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->rxspeed = -1; /* unknown or handled by MII */
+	dev->txspeed = -1;
 
 	net->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
 	if (!net->tstats)
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 407469ee224f..6a3677c0f113 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -53,6 +53,8 @@  struct usbnet {
 	u32			hard_mtu;	/* count any extra framing */
 	size_t			rx_urb_size;	/* size for rx urbs */
 	struct mii_if_info	mii;
+	long			rxspeed;	/* if MII is not used */
+	long			txspeed;	/* if MII is not used */
 
 	/* various kinds of pending driver work */
 	struct sk_buff_head	rxq;
@@ -267,6 +269,8 @@  extern void usbnet_purge_paused_rxq(struct usbnet *);
 
 extern int usbnet_get_link_ksettings_mdio(struct net_device *net,
 				     struct ethtool_link_ksettings *cmd);
+extern int usbnet_get_link_ksettings_internal(struct net_device *net,
+					struct ethtool_link_ksettings *cmd);
 extern int usbnet_set_link_ksettings_mdio(struct net_device *net,
 				     const struct ethtool_link_ksettings *cmd);
 extern u32 usbnet_get_link(struct net_device *net);