* [PATCH net-next 0/4] net: usb: move exported code to usbnet
@ 2026-07-02 14:25 Oliver Neukum
2026-07-02 14:25 ` [PATCH net-next 1/4] net: usb: move updating filter and status from cdc " Oliver Neukum
` (5 more replies)
0 siblings, 6 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
Some drivers are reusing common code originating in 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.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [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
* [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
* [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 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 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 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
* 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
* 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
* 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
end of thread, other threads:[~2026-07-03 14:59 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 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
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
2026-07-02 14:25 ` [PATCH net-next 4/4] net: usb: use cdc_state in " Oliver Neukum
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
2026-07-02 18:26 ` Manuel Ebner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox