Re: [PATCH v3 1/4] Simplify usbnet_cdc_update_filter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey,

I've encountered that same problem a few days ago, found this thread
and these (unmerged) patches, "ported" them to a more current version
of the kernel (wasn't much work, let's be honest), and I was wondering
if it would be possible to get them merged, because this is still a
problem with cdc_ncm.

Here's the three "up to date" patches (based on 5.8-rc5), they work
insofar as I'm running with them, the bug isn't there anymore (I get
ethernet multicast packets correctly), and there's no obvious bug. I'm
not a dev though, so I have no idea if these are formatted correctly,
if the patch separation is correct, or anything like that, I just think
it would be great if this could be merged into mainline!

On Sun, 2018-07-01 at 11:05 +0200, Miguel Rodríguez Pérez wrote:
> Remove some unneded varibles to make the code easier to read
> and, replace the generic usb_control_msg function for the
> more specific usbnet_write_cmd.
> 
> Signed-off-by: Miguel Rodríguez Pérez <miguel@xxxxxxxxxxxxx>
> NACKED-BY: Oliver Neukum <oneukum@xxxxxxxx>
> ---
>  drivers/net/usb/cdc_ether.c | 15 +++++----------
>  1 file changed, 5 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/usb/cdc_ether.c
> b/drivers/net/usb/cdc_ether.c
> index 178b956501a7..815ed0dc18fe 100644
> --- a/drivers/net/usb/cdc_ether.c
> +++ b/drivers/net/usb/cdc_ether.c
> @@ -77,9 +77,7 @@ static const u8 mbm_guid[16] = {
>  
>  static void usbnet_cdc_update_filter(struct usbnet *dev)
>  {
> -	struct cdc_state	*info = (void *) &dev->data;
> -	struct usb_interface	*intf = info->control;
> -	struct net_device	*net = dev->net;
> +	struct net_device *net = dev->net;
>  
>  	u16 cdc_filter = USB_CDC_PACKET_TYPE_DIRECTED
>  			| USB_CDC_PACKET_TYPE_BROADCAST;
> @@ -93,16 +91,13 @@ static void usbnet_cdc_update_filter(struct
> usbnet *dev)
>  	if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI))
>  		cdc_filter |= USB_CDC_PACKET_TYPE_ALL_MULTICAST;
>  
> -	usb_control_msg(dev->udev,
> -			usb_sndctrlpipe(dev->udev, 0),
> +	usbnet_write_cmd(dev,
>  			USB_CDC_SET_ETHERNET_PACKET_FILTER,
> -			USB_TYPE_CLASS | USB_RECIP_INTERFACE,
> +			USB_TYPE_CLASS | USB_DIR_OUT |
> USB_RECIP_INTERFACE,
>  			cdc_filter,
> -			intf->cur_altsetting->desc.bInterfaceNumber,
> +			dev->intf->cur_altsetting-
> >desc.bInterfaceNumber,
>  			NULL,
> -			0,
> -			USB_CTRL_SET_TIMEOUT
> -		);
> +			0);
>  }
>  
>  /* probes control interface, claims data interface, collects the
> bulk
-- 
Wxcafé <wxcafe@xxxxxxxxxx>
From fb4c24637de82a81374622d3f2f96452e0fb07d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Wxcaf=C3=A9?= <wxcafe@xxxxxxxxxx>
Date: Mon, 13 Jul 2020 16:16:14 -0400
Subject: [PATCH 1/3] net: cdc_ether: export generic usbnet_cdc_update_filter

This makes the function avaiable to other drivers, like cdn_ncm.

Other drivers will use different dev->data types, so the exported
function must not use it; instead the exported function takes an
additional pointer to the control interface.

Within cdc_ether the control interface is still taken from the control
field from struct cdc_state stored in dev->data.
---
 drivers/net/usb/cdc_ether.c | 24 ++++++++++++++++--------
 include/linux/usb/usbnet.h  |  2 ++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index a657943c9f01..b201adc885f6 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -63,10 +63,8 @@ static const u8 mbm_guid[16] = {
 	0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a,
 };
 
-static void usbnet_cdc_update_filter(struct usbnet *dev)
+void usbnet_cdc_update_filter(struct usbnet *dev, struct usb_interface *control)
 {
-	struct cdc_state	*info = (void *) &dev->data;
-	struct usb_interface	*intf = info->control;
 	struct net_device	*net = dev->net;
 
 	u16 cdc_filter = USB_CDC_PACKET_TYPE_DIRECTED
@@ -86,12 +84,22 @@ static void usbnet_cdc_update_filter(struct usbnet *dev)
 			USB_CDC_SET_ETHERNET_PACKET_FILTER,
 			USB_TYPE_CLASS | USB_RECIP_INTERFACE,
 			cdc_filter,
-			intf->cur_altsetting->desc.bInterfaceNumber,
+			control->cur_altsetting->desc.bInterfaceNumber,
 			NULL,
 			0,
 			USB_CTRL_SET_TIMEOUT
 		);
 }
+EXPORT_SYMBOL_GPL(usbnet_cdc_update_filter);
+
+/* the control interface is not always necessarily the probed interface
+ * dev->intf, see rndis handling in usbnet_generic_cdc_bind.
+ */
+static void usbnet_cdc_ether_update_filter(struct usbnet *dev) {
+	struct cdc_state *info = (void *)&dev->data;
+
+	usbnet_cdc_update_filter(dev, info->control);
+}
 
 /* probes control interface, claims data interface, collects the bulk
  * endpoints, activates data interface (if needed), maybe sets MTU.
@@ -336,7 +344,7 @@ int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
 	 * don't do reset all the way. So the packet filter should
 	 * be set to a sane initial value.
 	 */
-	usbnet_cdc_update_filter(dev);
+	usbnet_cdc_ether_update_filter(dev);
 
 bail_out:
 	return rv;
@@ -514,7 +522,7 @@ static const struct driver_info	cdc_info = {
 	.bind =		usbnet_cdc_bind,
 	.unbind =	usbnet_cdc_unbind,
 	.status =	usbnet_cdc_status,
-	.set_rx_mode =	usbnet_cdc_update_filter,
+	.set_rx_mode =	usbnet_cdc_ether_update_filter,
 	.manage_power =	usbnet_manage_power,
 };
 
@@ -524,7 +532,7 @@ static const struct driver_info	zte_cdc_info = {
 	.bind =		usbnet_cdc_zte_bind,
 	.unbind =	usbnet_cdc_unbind,
 	.status =	usbnet_cdc_zte_status,
-	.set_rx_mode =	usbnet_cdc_update_filter,
+	.set_rx_mode =	usbnet_cdc_ether_update_filter,
 	.manage_power =	usbnet_manage_power,
 	.rx_fixup = usbnet_cdc_zte_rx_fixup,
 };
@@ -535,7 +543,7 @@ static const struct driver_info wwan_info = {
 	.bind =		usbnet_cdc_bind,
 	.unbind =	usbnet_cdc_unbind,
 	.status =	usbnet_cdc_status,
-	.set_rx_mode =	usbnet_cdc_update_filter,
+	.set_rx_mode =	usbnet_cdc_ether_update_filter,
 	.manage_power =	usbnet_manage_power,
 };
 
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index b0bff3083278..387f3da06e9d 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -286,4 +286,6 @@ extern void usbnet_update_max_qlen(struct usbnet *dev);
 extern void usbnet_get_stats64(struct net_device *dev,
 			       struct rtnl_link_stats64 *stats);
 
+extern void usbnet_cdc_update_filter(struct usbnet *, struct usb_interface *);
+
 #endif /* __LINUX_USB_USBNET_H */
-- 
2.27.0

From 315f7e56a4a49e9cbafbd9a88444f8b213524d4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Wxcaf=C3=A9?= <wxcafe@xxxxxxxxxx>
Date: Mon, 13 Jul 2020 16:17:21 -0400
Subject: [PATCH 2/3] net: usbnet: export usbnet_set_rx_mode

---
 drivers/net/usb/usbnet.c   | 3 ++-
 include/linux/usb/usbnet.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 5ec97def3513..e45935a5856a 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1108,12 +1108,13 @@ static void __handle_link_change(struct usbnet *dev)
 	clear_bit(EVENT_LINK_CHANGE, &dev->flags);
 }
 
-static void usbnet_set_rx_mode(struct net_device *net)
+void usbnet_set_rx_mode(struct net_device *net)
 {
 	struct usbnet		*dev = netdev_priv(net);
 
 	usbnet_defer_kevent(dev, EVENT_SET_RX_MODE);
 }
+EXPORT_SYMBOL_GPL(usbnet_set_rx_mode);
 
 static void __handle_set_rx_mode(struct usbnet *dev)
 {
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 387f3da06e9d..455b568ff4dd 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -254,6 +254,7 @@ extern int usbnet_stop(struct net_device *net);
 extern netdev_tx_t usbnet_start_xmit(struct sk_buff *skb,
 				     struct net_device *net);
 extern void usbnet_tx_timeout(struct net_device *net, unsigned int txqueue);
+extern void usbnet_set_rx_mode(struct net_device *net);
 extern int usbnet_change_mtu(struct net_device *net, int new_mtu);
 
 extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
-- 
2.27.0

From b716a0fa777a9d7dee854b768efc3fff9074a2b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Wxcaf=C3=A9?= <wxcafe@xxxxxxxxxx>
Date: Mon, 13 Jul 2020 16:20:41 -0400
Subject: [PATCH 3/3] net: cdc_ncm: hook into set_rx_mode to admit multicast

Use usbnet_cdc_update_filter from cdc_ether to admit all multicast
traffic if there is more than one multicast filter configured.
---
 drivers/net/usb/cdc_ncm.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 8929669b5e6d..688d7e9df41e 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -792,6 +792,7 @@ static const struct net_device_ops cdc_ncm_netdev_ops = {
 	.ndo_stop	     = usbnet_stop,
 	.ndo_start_xmit	     = usbnet_start_xmit,
 	.ndo_tx_timeout	     = usbnet_tx_timeout,
+	.ndo_set_rx_mode     = usbnet_set_rx_mode,
 	.ndo_get_stats64     = usbnet_get_stats64,
 	.ndo_change_mtu	     = cdc_ncm_change_mtu,
 	.ndo_set_mac_address = eth_mac_addr,
@@ -1885,6 +1886,13 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
 	}
 }
 
+/* the control interface is always the probed one */
+static void usbnet_cdc_ncm_update_filter(struct usbnet *dev)
+{
+	usbnet_cdc_update_filter(dev, dev->intf);
+}
+
+
 static const struct driver_info cdc_ncm_info = {
 	.description = "CDC NCM",
 	.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
@@ -1895,6 +1903,7 @@ static const struct driver_info cdc_ncm_info = {
 	.status = cdc_ncm_status,
 	.rx_fixup = cdc_ncm_rx_fixup,
 	.tx_fixup = cdc_ncm_tx_fixup,
+	.set_rx_mode = usbnet_cdc_ncm_update_filter,
 };
 
 /* Same as cdc_ncm_info, but with FLAG_WWAN */
@@ -1908,6 +1917,7 @@ static const struct driver_info wwan_info = {
 	.status = cdc_ncm_status,
 	.rx_fixup = cdc_ncm_rx_fixup,
 	.tx_fixup = cdc_ncm_tx_fixup,
+	.set_rx_mode = usbnet_cdc_ncm_update_filter,
 };
 
 /* Same as wwan_info, but with FLAG_NOARP  */
@@ -1921,6 +1931,7 @@ static const struct driver_info wwan_noarp_info = {
 	.status = cdc_ncm_status,
 	.rx_fixup = cdc_ncm_rx_fixup,
 	.tx_fixup = cdc_ncm_tx_fixup,
+	.set_rx_mode = usbnet_cdc_ncm_update_filter,
 };
 
 static const struct usb_device_id cdc_devs[] = {
-- 
2.27.0


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux