* [PATCH net-next 1/4] net: usb: move updating filter and status from cdc to usbnet
2026-07-02 14:25 [PATCH net-next 0/4] net: usb: move exported code to usbnet Oliver Neukum
@ 2026-07-02 14:25 ` Oliver Neukum
2026-07-02 17:59 ` Manuel Ebner
2026-07-02 18:20 ` Andrew Lunn
2026-07-02 14:25 ` [PATCH net-next 2/4] net: usb: centralize usbnet_cdc_zte_rx_fixup in usbnet Oliver Neukum
` (4 subsequent siblings)
5 siblings, 2 replies; 12+ messages in thread
From: Oliver Neukum @ 2026-07-02 14:25 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, shaoxul, netdev,
linux-usb, linux-kernel
Cc: Oliver Neukum
These helpers are used by multiple drivers and do not depend
on the rest of cdc. Leavin them in a cdc driver means that
more drivers are loaded just for infrastructure, not hardware
support.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
drivers/net/usb/cdc_ether.c | 75 ------------------------------------
drivers/net/usb/usbnet.c | 76 +++++++++++++++++++++++++++++++++++++
2 files changed, 76 insertions(+), 75 deletions(-)
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index a0a5740590b9..b4df32e18461 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -63,35 +63,6 @@ static const u8 mbm_guid[16] = {
0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a,
};
-void usbnet_cdc_update_filter(struct usbnet *dev)
-{
- struct net_device *net = dev->net;
-
- u16 cdc_filter = USB_CDC_PACKET_TYPE_DIRECTED
- | USB_CDC_PACKET_TYPE_BROADCAST;
-
- /* filtering on the device is an optional feature and not worth
- * the hassle so we just roughly care about snooping and if any
- * multicast is requested, we take every multicast
- */
- if (net->flags & IFF_PROMISC)
- cdc_filter |= USB_CDC_PACKET_TYPE_PROMISCUOUS;
- 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),
- USB_CDC_SET_ETHERNET_PACKET_FILTER,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- cdc_filter,
- dev->intf->cur_altsetting->desc.bInterfaceNumber,
- NULL,
- 0,
- USB_CTRL_SET_TIMEOUT
- );
-}
-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,
@@ -400,52 +371,6 @@ EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
* (by Brad Hards) talked with, with more functionality.
*/
-static void speed_change(struct usbnet *dev, __le32 *speeds)
-{
- 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)
-{
- struct usb_cdc_notification *event;
-
- if (urb->actual_length < sizeof(*event))
- return;
-
- /* SPEED_CHANGE can get split into two 8-byte packets */
- if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
- speed_change(dev, (__le32 *) urb->transfer_buffer);
- return;
- }
-
- event = urb->transfer_buffer;
- switch (event->bNotificationType) {
- case USB_CDC_NOTIFY_NETWORK_CONNECTION:
- netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
- event->wValue ? "on" : "off");
- if (netif_carrier_ok(dev->net) != !!event->wValue)
- usbnet_link_change(dev, !!event->wValue, 0);
- break;
- case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
- netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n",
- urb->actual_length);
- if (urb->actual_length != (sizeof(*event) + 8))
- set_bit(EVENT_STS_SPLIT, &dev->flags);
- else
- 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.
- */
- default:
- netdev_err(dev->net, "CDC: unexpected notification %02x!\n",
- event->bNotificationType);
- break;
- }
-}
-EXPORT_SYMBOL_GPL(usbnet_cdc_status);
-
int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
{
int status;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 25518635b7b7..5544af1f4aa5 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/usb/cdc.h>
#include <linux/ctype.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
@@ -2271,6 +2272,81 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
}
EXPORT_SYMBOL_GPL(usbnet_write_cmd_async);
+
+void usbnet_cdc_update_filter(struct usbnet *dev)
+{
+ struct net_device *net = dev->net;
+
+ u16 cdc_filter = USB_CDC_PACKET_TYPE_DIRECTED
+ | USB_CDC_PACKET_TYPE_BROADCAST;
+
+ /* filtering on the device is an optional feature and not worth
+ * the hassle so we just roughly care about snooping and if any
+ * multicast is requested, we take every multicast
+ */
+ if (net->flags & IFF_PROMISC)
+ cdc_filter |= USB_CDC_PACKET_TYPE_PROMISCUOUS;
+ 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),
+ USB_CDC_SET_ETHERNET_PACKET_FILTER,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ cdc_filter,
+ dev->intf->cur_altsetting->desc.bInterfaceNumber,
+ NULL,
+ 0,
+ USB_CTRL_SET_TIMEOUT
+ );
+}
+EXPORT_SYMBOL_GPL(usbnet_cdc_update_filter);
+
+static void speed_change(struct usbnet *dev, __le32 *speeds)
+{
+ 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)
+{
+ struct usb_cdc_notification *event;
+
+ if (urb->actual_length < sizeof(*event))
+ return;
+
+ /* SPEED_CHANGE can get split into two 8-byte packets */
+ if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
+ speed_change(dev, (__le32 *)urb->transfer_buffer);
+ return;
+ }
+
+ event = urb->transfer_buffer;
+ switch (event->bNotificationType) {
+ case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+ netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
+ event->wValue ? "on" : "off");
+ if (netif_carrier_ok(dev->net) != !!event->wValue)
+ usbnet_link_change(dev, !!event->wValue, 0);
+ break;
+ case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
+ netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n",
+ urb->actual_length);
+ if (urb->actual_length != (sizeof(*event) + 8))
+ set_bit(EVENT_STS_SPLIT, &dev->flags);
+ else
+ 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.
+ */
+ default:
+ netdev_err(dev->net, "CDC: unexpected notification %02x!\n",
+ event->bNotificationType);
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(usbnet_cdc_status);
/*-------------------------------------------------------------------------*/
static int __init usbnet_init(void)
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH net-next 1/4] net: usb: move updating filter and status from cdc to usbnet
2026-07-02 14:25 ` [PATCH net-next 1/4] net: usb: move updating filter and status from cdc " Oliver Neukum
@ 2026-07-02 17:59 ` Manuel Ebner
2026-07-02 18:20 ` Andrew Lunn
1 sibling, 0 replies; 12+ messages in thread
From: Manuel Ebner @ 2026-07-02 17:59 UTC (permalink / raw)
To: Oliver Neukum, andrew+netdev, davem, edumazet, kuba, pabeni,
shaoxul, netdev, linux-usb, linux-kernel
Hi,
I have a couple suggestions for you patch. Some parts are
weird to read - it could also be that my perception today is off.
On Thu, 2026-07-02 at 16:25 +0200, Oliver Neukum wrote:
> These helpers are used by multiple drivers and do not depend
"and do not only depend on cdc core. They also depend on
other cdc drivers."
is this better?
> on the rest of cdc. Leavin them in a cdc driver means that
/Leavin/Leaving/
> more drivers are loaded just for infrastructure, not hardware
just for the support of other drivers, not their hardware.
> support.
>
> Signed-off-by: Oliver Neukum <oneukum@suse.com>
> ---
> drivers/net/usb/cdc_ether.c | 75 ------------------------------------
> drivers/net/usb/usbnet.c | 76 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 76 insertions(+), 75 deletions(-)
>
> diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
> index a0a5740590b9..b4df32e18461 100644
> --- a/drivers/net/usb/cdc_ether.c
> +++ b/drivers/net/usb/cdc_ether.c
> @@ -63,35 +63,6 @@ static const u8 mbm_guid[16] = {
> 0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a,
> };
>
> -void usbnet_cdc_update_filter(struct usbnet *dev)
> -{
> - struct net_device *net = dev->net;
> -
> - u16 cdc_filter = USB_CDC_PACKET_TYPE_DIRECTED
> - | USB_CDC_PACKET_TYPE_BROADCAST;
> -
> - /* filtering on the device is an optional feature and not worth
> - * the hassle so we just roughly care about snooping and if any
> - * multicast is requested, we take every multicast
> - */
> - if (net->flags & IFF_PROMISC)
> - cdc_filter |= USB_CDC_PACKET_TYPE_PROMISCUOUS;
> - 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),
> - USB_CDC_SET_ETHERNET_PACKET_FILTER,
> - USB_TYPE_CLASS | USB_RECIP_INTERFACE,
> - cdc_filter,
> - dev->intf->cur_altsetting->desc.bInterfaceNumber,
> - NULL,
> - 0,
> - USB_CTRL_SET_TIMEOUT
> - );
> -}
> -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,
> @@ -400,52 +371,6 @@ EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
> * (by Brad Hards) talked with, with more functionality.
> */
>
> -static void speed_change(struct usbnet *dev, __le32 *speeds)
> -{
> - 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)
> -{
> - struct usb_cdc_notification *event;
> -
> - if (urb->actual_length < sizeof(*event))
> - return;
> -
> - /* SPEED_CHANGE can get split into two 8-byte packets */
> - if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
> - speed_change(dev, (__le32 *) urb->transfer_buffer);
> - return;
> - }
> -
> - event = urb->transfer_buffer;
> - switch (event->bNotificationType) {
> - case USB_CDC_NOTIFY_NETWORK_CONNECTION:
> - netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
> - event->wValue ? "on" : "off");
> - if (netif_carrier_ok(dev->net) != !!event->wValue)
> - usbnet_link_change(dev, !!event->wValue, 0);
> - break;
> - case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
> - netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n",
> - urb->actual_length);
> - if (urb->actual_length != (sizeof(*event) + 8))
> - set_bit(EVENT_STS_SPLIT, &dev->flags);
> - else
> - 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.
> - */
> - default:
> - netdev_err(dev->net, "CDC: unexpected notification %02x!\n",
> - event->bNotificationType);
> - break;
> - }
> -}
> -EXPORT_SYMBOL_GPL(usbnet_cdc_status);
> -
> int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
> {
> int status;
> diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
> index 25518635b7b7..5544af1f4aa5 100644
> --- a/drivers/net/usb/usbnet.c
> +++ b/drivers/net/usb/usbnet.c
> @@ -22,6 +22,7 @@
> #include <linux/init.h>
> #include <linux/netdevice.h>
> #include <linux/etherdevice.h>
> +#include <linux/usb/cdc.h>
why do you put it there?
it could be alphabetical instead.
> #include <linux/ctype.h>
> #include <linux/ethtool.h>
> #include <linux/workqueue.h>
> @@ -2271,6 +2272,81 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8
> reqtype,
>
> }
> EXPORT_SYMBOL_GPL(usbnet_write_cmd_async);
> +
> +void usbnet_cdc_update_filter(struct usbnet *dev)
> +{
> + struct net_device *net = dev->net;
> +
> + u16 cdc_filter = USB_CDC_PACKET_TYPE_DIRECTED
> + | USB_CDC_PACKET_TYPE_BROADCAST;
> +
Multi-line-comments in coding-style:
/*
* filtering on ..
> + /* filtering on the device is an optional feature and not worth
> + * the hassle so we just roughly care about snooping and if any
> + * multicast is requested, we take every multicast
, we take that multicast.
also that's a pretty long sentence.
> + */
> + if (net->flags & IFF_PROMISC)
> + cdc_filter |= USB_CDC_PACKET_TYPE_PROMISCUOUS;
> + 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),
> + USB_CDC_SET_ETHERNET_PACKET_FILTER,
> + USB_TYPE_CLASS | USB_RECIP_INTERFACE,
> + cdc_filter,
> + dev->intf->cur_altsetting->desc.bInterfaceNumber,
> + NULL,
> + 0,
> + USB_CTRL_SET_TIMEOUT
> + );
> +}
> +EXPORT_SYMBOL_GPL(usbnet_cdc_update_filter);
> +
> +static void speed_change(struct usbnet *dev, __le32 *speeds)
> +{
> + 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)
> +{
> + struct usb_cdc_notification *event;
> +
> + if (urb->actual_length < sizeof(*event))
> + return;
> +
> + /* SPEED_CHANGE can get split into two 8-byte packets */
> + if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
> + speed_change(dev, (__le32 *)urb->transfer_buffer);
> + return;
> + }
> +
> + event = urb->transfer_buffer;
> + switch (event->bNotificationType) {
> + case USB_CDC_NOTIFY_NETWORK_CONNECTION:
> + netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
> + event->wValue ? "on" : "off");
> + if (netif_carrier_ok(dev->net) != !!event->wValue)
> + usbnet_link_change(dev, !!event->wValue, 0);
> + break;
> + case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
> + netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n",
> + urb->actual_length);
> + if (urb->actual_length != (sizeof(*event) + 8))
> + set_bit(EVENT_STS_SPLIT, &dev->flags);
> + else
> + speed_change(dev, (__le32 *)&event[1]);
> + break;
/*
* USB ..
> + /* USB_CDC_NOTIFY_RESPONSE_AVAILABLE can happen too (e.g. RNDIS),
> + * but there are no standard formats for the response data.
> + */
> + default:
> + netdev_err(dev->net, "CDC: unexpected notification %02x!\n",
> + event->bNotificationType);
> + break;
> + }
> +}
> +EXPORT_SYMBOL_GPL(usbnet_cdc_status);
> /*-------------------------------------------------------------------------*/
>
> static int __init usbnet_init(void)
You can add my
Reviewed-by: Manuel Ebner <manuelebner@mailbox.org>
Thanks
Manuel
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH net-next 1/4] net: usb: move updating filter and status from cdc to usbnet
2026-07-02 14:25 ` [PATCH net-next 1/4] net: usb: move updating filter and status from cdc " Oliver Neukum
2026-07-02 17:59 ` Manuel Ebner
@ 2026-07-02 18:20 ` Andrew Lunn
1 sibling, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2026-07-02 18:20 UTC (permalink / raw)
To: Oliver Neukum
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, shaoxul, netdev,
linux-usb, linux-kernel
On Thu, Jul 02, 2026 at 04:25:30PM +0200, Oliver Neukum wrote:
> These helpers are used by multiple drivers and do not depend
> on the rest of cdc. Leavin them in a cdc driver means that
leaving.
> more drivers are loaded just for infrastructure, not hardware
> support.
Can there also be changes to Kconfig removing the dependency on
cdc_ether for some drivers? They now only depend on usbnet?
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next 2/4] net: usb: centralize usbnet_cdc_zte_rx_fixup in usbnet
2026-07-02 14:25 [PATCH net-next 0/4] net: usb: move exported code to usbnet Oliver Neukum
2026-07-02 14:25 ` [PATCH net-next 1/4] net: usb: move updating filter and status from cdc " Oliver Neukum
@ 2026-07-02 14:25 ` Oliver Neukum
2026-07-02 18:19 ` Manuel Ebner
2026-07-02 14:25 ` [PATCH net-next 3/4] net: usb: usbnet: add cdc_state to struct usbnet Oliver Neukum
` (3 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Oliver Neukum @ 2026-07-02 14:25 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, shaoxul, netdev,
linux-usb, linux-kernel
Cc: Oliver Neukum
This helper is used by multiple drivers using usbnet.
It is better to be provided by usbnet than one of them.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
drivers/net/usb/cdc_ether.c | 19 -------------------
drivers/net/usb/usbnet.c | 19 +++++++++++++++++++
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index b4df32e18461..e688fb99c61d 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -404,25 +404,6 @@ static int usbnet_cdc_zte_bind(struct usbnet *dev, struct usb_interface *intf)
return status;
}
-/* Make sure packets have correct destination MAC address
- *
- * A firmware bug observed on some devices (ZTE MF823/831/910) is that the
- * device sends packets with a static, bogus, random MAC address (event if
- * device MAC address has been updated). Always set MAC address to that of the
- * device.
- */
-int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- if (skb->len < ETH_HLEN || !(skb->data[0] & 0x02))
- return 1;
-
- skb_reset_mac_header(skb);
- ether_addr_copy(eth_hdr(skb)->h_dest, dev->net->dev_addr);
-
- return 1;
-}
-EXPORT_SYMBOL_GPL(usbnet_cdc_zte_rx_fixup);
-
/* Ensure correct link state
*
* Some devices (ZTE MF823/831/910) export two carrier on notifications when
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 5544af1f4aa5..7beea6d0e731 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -2347,6 +2347,25 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
}
}
EXPORT_SYMBOL_GPL(usbnet_cdc_status);
+
+/* Make sure packets have correct destination MAC address
+ *
+ * A firmware bug observed on some devices (ZTE MF823/831/910) is that the
+ * device sends packets with a static, bogus, random MAC address (event if
+ * device MAC address has been updated). Always set MAC address to that of the
+ * device.
+ */
+int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ if (skb->len < ETH_HLEN || !(skb->data[0] & 0x02))
+ return 1;
+
+ skb_reset_mac_header(skb);
+ ether_addr_copy(eth_hdr(skb)->h_dest, dev->net->dev_addr);
+
+ return 1;
+}
+EXPORT_SYMBOL_GPL(usbnet_cdc_zte_rx_fixup);
/*-------------------------------------------------------------------------*/
static int __init usbnet_init(void)
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH net-next 2/4] net: usb: centralize usbnet_cdc_zte_rx_fixup in usbnet
2026-07-02 14:25 ` [PATCH net-next 2/4] net: usb: centralize usbnet_cdc_zte_rx_fixup in usbnet Oliver Neukum
@ 2026-07-02 18:19 ` Manuel Ebner
0 siblings, 0 replies; 12+ messages in thread
From: Manuel Ebner @ 2026-07-02 18:19 UTC (permalink / raw)
To: Oliver Neukum, andrew+netdev, davem, edumazet, kuba, pabeni,
shaoxul, netdev, linux-usb, linux-kernel
On Thu, 2026-07-02 at 16:25 +0200, Oliver Neukum wrote:
> This helper is used by multiple drivers using usbnet.
> It is better to be provided by usbnet than one of them.
>
> Signed-off-by: Oliver Neukum <oneukum@suse.com>
> ---
> drivers/net/usb/cdc_ether.c | 19 -------------------
> drivers/net/usb/usbnet.c | 19 +++++++++++++++++++
> 2 files changed, 19 insertions(+), 19 deletions(-)
>
> ...
>
> diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
> index 5544af1f4aa5..7beea6d0e731 100644
> --- a/drivers/net/usb/usbnet.c
> +++ b/drivers/net/usb/usbnet.c
> @@ -2347,6 +2347,25 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
> }
> }
> EXPORT_SYMBOL_GPL(usbnet_cdc_status);
> +
> +/* Make sure packets have correct destination MAC address
/*
* Make sure packets have the correct destination MAC address
> + *
> + * A firmware bug observed on some devices (ZTE MF823/831/910) is that the
> + * device sends packets with a static, bogus, random MAC address (event if
(even if the device ...
> + * device MAC address has been updated). Always set MAC address to that of the
> + * device.
Always set the MAC address to the one of your device.
Thanks
Manuel
> + * device.
> + */
> +int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
> +{
> + if (skb->len < ETH_HLEN || !(skb->data[0] & 0x02))
> + return 1;
> +
> + skb_reset_mac_header(skb);
> + ether_addr_copy(eth_hdr(skb)->h_dest, dev->net->dev_addr);
> +
> + return 1;
> +}
> +EXPORT_SYMBOL_GPL(usbnet_cdc_zte_rx_fixup);
> /*-------------------------------------------------------------------------*/
>
> static int __init usbnet_init(void)
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next 3/4] net: usb: usbnet: add cdc_state to struct usbnet
2026-07-02 14:25 [PATCH net-next 0/4] net: usb: move exported code to usbnet Oliver Neukum
2026-07-02 14:25 ` [PATCH net-next 1/4] net: usb: move updating filter and status from cdc " Oliver Neukum
2026-07-02 14:25 ` [PATCH net-next 2/4] net: usb: centralize usbnet_cdc_zte_rx_fixup in usbnet Oliver Neukum
@ 2026-07-02 14:25 ` Oliver Neukum
2026-07-02 14:25 ` [PATCH net-next 4/4] net: usb: use cdc_state in " Oliver Neukum
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Oliver Neukum @ 2026-07-02 14:25 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, shaoxul, netdev,
linux-usb, linux-kernel
Cc: Oliver Neukum
This allows centralisation of code using cdc_state in usbnet, reducing
code duplication. No functional change intended.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
include/linux/usb/usbnet.h | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index bbf799ccf3b3..79f48eb388ee 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -16,6 +16,14 @@
#include <linux/usb.h>
#include <linux/spinlock.h>
+struct cdc_state {
+ struct usb_cdc_header_desc *header;
+ struct usb_cdc_union_desc *u;
+ struct usb_cdc_ether_desc *ether;
+ struct usb_interface *control;
+ struct usb_interface *data;
+};
+
/* interface from usbnet core to each USB networking link we handle */
struct usbnet {
/* housekeeping */
@@ -41,6 +49,7 @@ struct usbnet {
/* protocol/interface state */
struct net_device *net;
int msg_enable;
+ struct cdc_state cdc; /* too common to leave out*/
unsigned long data[5];
u32 xid;
u32 hard_mtu; /* count any extra framing */
@@ -211,13 +220,6 @@ extern int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
* (notably, using multiple interfaces according to the CDC
* union descriptor) get some helper code.
*/
-struct cdc_state {
- struct usb_cdc_header_desc *header;
- struct usb_cdc_union_desc *u;
- struct usb_cdc_ether_desc *ether;
- struct usb_interface *control;
- struct usb_interface *data;
-};
extern void usbnet_cdc_update_filter(struct usbnet *dev);
extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *);
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH net-next 4/4] net: usb: use cdc_state in struct usbnet
2026-07-02 14:25 [PATCH net-next 0/4] net: usb: move exported code to usbnet Oliver Neukum
` (2 preceding siblings ...)
2026-07-02 14:25 ` [PATCH net-next 3/4] net: usb: usbnet: add cdc_state to struct usbnet Oliver Neukum
@ 2026-07-02 14:25 ` Oliver Neukum
2026-07-02 18:15 ` [PATCH net-next 0/4] net: usb: move exported code to usbnet Andrew Lunn
2026-07-02 18:26 ` Manuel Ebner
5 siblings, 0 replies; 12+ messages in thread
From: Oliver Neukum @ 2026-07-02 14:25 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, shaoxul, netdev,
linux-usb, linux-kernel
Cc: Oliver Neukum
Remove private copies as now a central state can be used.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
drivers/net/usb/cdc_ether.c | 9 +++------
drivers/net/usb/rndis_host.c | 6 +++---
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index e688fb99c61d..76ad4ffa950a 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -85,7 +85,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
u8 *buf = intf->cur_altsetting->extra;
int len = intf->cur_altsetting->extralen;
struct usb_interface_descriptor *d;
- struct cdc_state *info = (void *) &dev->data;
+ struct cdc_state *info = &dev->cdc;
int status = -ENODEV;
int rndis;
bool android_rndis_quirk = false;
@@ -336,7 +336,7 @@ EXPORT_SYMBOL_GPL(usbnet_ether_cdc_bind);
void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct cdc_state *info = (void *) &dev->data;
+ struct cdc_state *info = &dev->cdc;
struct usb_driver *driver = driver_of(intf);
/* combined interface - nothing to do */
@@ -374,10 +374,7 @@ EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
{
int status;
- struct cdc_state *info = (void *) &dev->data;
-
- BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data)
- < sizeof(struct cdc_state)));
+ struct cdc_state *info = &dev->cdc;
status = usbnet_ether_cdc_bind(dev, intf);
if (status < 0)
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 5e39d05a2d7b..d539654687c3 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -57,7 +57,7 @@ EXPORT_SYMBOL_GPL(rndis_status);
static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
int buflen)
{
- struct cdc_state *info = (void *)&dev->data;
+ struct cdc_state *info = &dev->cdc;
struct device *udev = &info->control->dev;
if (dev->driver_info->indication) {
@@ -90,7 +90,7 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
*/
int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
{
- struct cdc_state *info = (void *) &dev->data;
+ struct cdc_state *info = &dev->cdc;
struct usb_cdc_notification notification;
int master_ifnum;
int retval;
@@ -290,7 +290,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
{
int retval;
struct net_device *net = dev->net;
- struct cdc_state *info = (void *) &dev->data;
+ struct cdc_state *info = &dev->cdc;
union {
void *buf;
struct rndis_msg_hdr *header;
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH net-next 0/4] net: usb: move exported code to usbnet
2026-07-02 14:25 [PATCH net-next 0/4] net: usb: move exported code to usbnet Oliver Neukum
` (3 preceding siblings ...)
2026-07-02 14:25 ` [PATCH net-next 4/4] net: usb: use cdc_state in " Oliver Neukum
@ 2026-07-02 18:15 ` Andrew Lunn
2026-07-03 10:16 ` Oliver Neukum
2026-07-02 18:26 ` Manuel Ebner
5 siblings, 1 reply; 12+ messages in thread
From: Andrew Lunn @ 2026-07-02 18:15 UTC (permalink / raw)
To: Oliver Neukum
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, shaoxul, netdev,
linux-usb, linux-kernel
On Thu, Jul 02, 2026 at 04:25:29PM +0200, Oliver Neukum wrote:
> Some drivers are reusing common code originating in other drivers.
> This means that two drivers need to be loaded for one device.
Maybe consider using 'framework' or 'library', rather than driver,
when referring to the shared code?
I tend to think of a driver as the leaf node which probes based on
enumeration of a bus. But usbnet.c itself is never probed.
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH net-next 0/4] net: usb: move exported code to usbnet
2026-07-02 18:15 ` [PATCH net-next 0/4] net: usb: move exported code to usbnet Andrew Lunn
@ 2026-07-03 10:16 ` Oliver Neukum
2026-07-03 14:59 ` Andrew Lunn
0 siblings, 1 reply; 12+ messages in thread
From: Oliver Neukum @ 2026-07-03 10:16 UTC (permalink / raw)
To: Andrew Lunn, Oliver Neukum
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, shaoxul, netdev,
linux-usb, linux-kernel
On 02.07.26 20:15, Andrew Lunn wrote:
> On Thu, Jul 02, 2026 at 04:25:29PM +0200, Oliver Neukum wrote:
>> Some drivers are reusing common code originating in other drivers.
>> This means that two drivers need to be loaded for one device.
>
> Maybe consider using 'framework' or 'library', rather than driver,
> when referring to the shared code?
>
> I tend to think of a driver as the leaf node which probes based on
> enumeration of a bus. But usbnet.c itself is never probed.
Yes, I also think of a leaf node when a "driver" is referred to.
That is the very point. Currently you need _two_ drivers and
usbnet for some devices.
Should I reformulate? If so, how exactly?
Regards
Oliver
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 0/4] net: usb: move exported code to usbnet
2026-07-03 10:16 ` Oliver Neukum
@ 2026-07-03 14:59 ` Andrew Lunn
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2026-07-03 14:59 UTC (permalink / raw)
To: Oliver Neukum
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, shaoxul, netdev,
linux-usb, linux-kernel
On Fri, Jul 03, 2026 at 12:16:20PM +0200, Oliver Neukum wrote:
> On 02.07.26 20:15, Andrew Lunn wrote:
> > On Thu, Jul 02, 2026 at 04:25:29PM +0200, Oliver Neukum wrote:
> > > Some drivers are reusing common code originating in other drivers.
> > > This means that two drivers need to be loaded for one device.
> >
> > Maybe consider using 'framework' or 'library', rather than driver,
> > when referring to the shared code?
> >
> > I tend to think of a driver as the leaf node which probes based on
> > enumeration of a bus. But usbnet.c itself is never probed.
>
> Yes, I also think of a leaf node when a "driver" is referred to.
> That is the very point. Currently you need _two_ drivers and
> usbnet for some devices.
> Should I reformulate? If so, how exactly?
Maybe give examples? List the two drivers used for one device?
cdc_ether.c is being used both as a driver and a library? The
EXPORT_SYMBOL_GPL() make this clear, a driver would normally not need
exports. The patchset starts to make cdc_ether.c a pure driver, moving
some of the shared code into the usbnet library.
Just to be clear, i think what you are doing is correct, i just had
problems understanding the commit message.
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 0/4] net: usb: move exported code to usbnet
2026-07-02 14:25 [PATCH net-next 0/4] net: usb: move exported code to usbnet Oliver Neukum
` (4 preceding siblings ...)
2026-07-02 18:15 ` [PATCH net-next 0/4] net: usb: move exported code to usbnet Andrew Lunn
@ 2026-07-02 18:26 ` Manuel Ebner
5 siblings, 0 replies; 12+ messages in thread
From: Manuel Ebner @ 2026-07-02 18:26 UTC (permalink / raw)
To: Oliver Neukum, andrew+netdev, davem, edumazet, kuba, pabeni,
shaoxul, netdev, linux-usb, linux-kernel
Hallo,
On Thu, 2026-07-02 at 16:25 +0200, Oliver Neukum wrote:
I know this mail doesn't matter much, but i can't leave it as is.
> Some drivers are reusing common code originating in other drivers.
Some drivers are using code from other drivers.
> This means that two drivers need to be loaded for one device.
> Also maintainability is reduced if changes in one driver affect
> another driver.
> Shift common code to usbnet.
You can add my
Reviewed-by: Manuel Ebner <manuelebner@mailbox.org>
to the series.
Thanks
Manuel
^ permalink raw reply [flat|nested] 12+ messages in thread