From: Oliver Neukum <oneukum@suse.com>
To: andrew@lunn.ch, bjorn@mork.no, netdev@vger.kernel.org
Cc: Oliver Neukum <oneukum@suse.com>
Subject: [RFCv2 11/13] net: usb: cdc_ncm: use dynamic private allocation
Date: Tue, 3 Mar 2026 15:50:31 +0100 [thread overview]
Message-ID: <20260303145242.1377514-11-oneukum@suse.com> (raw)
In-Reply-To: <20260303145242.1377514-1-oneukum@suse.com>
The old style private room was too small for cdc_ncm.
With dynamic allocation that factor is gone.
Remove handling private allocations in the driver.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
drivers/net/usb/cdc_ncm.c | 78 +++++++++++++++++----------------------
1 file changed, 34 insertions(+), 44 deletions(-)
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 7057c6c0cfc6..91da42a778f4 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -107,7 +107,7 @@ static void cdc_ncm_get_ethtool_stats(struct net_device *netdev,
u64 *data)
{
struct usbnet *dev = netdev_priv(netdev);
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
int i;
char *p = NULL;
@@ -149,7 +149,7 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = {
static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
u32 val, max, min;
/* clamp new_rx to sane values */
@@ -172,7 +172,7 @@ static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx)
static u32 cdc_ncm_check_tx_max(struct usbnet *dev, u32 new_tx)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
u32 val, max, min;
/* clamp new_tx to sane values */
@@ -202,7 +202,7 @@ static ssize_t min_tx_pkt_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
return sprintf(buf, "%u\n", ctx->min_tx_pkt);
}
@@ -211,7 +211,7 @@ static ssize_t rx_max_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
return sprintf(buf, "%u\n", ctx->rx_max);
}
@@ -220,7 +220,7 @@ static ssize_t tx_max_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
return sprintf(buf, "%u\n", ctx->tx_max);
}
@@ -229,7 +229,7 @@ static ssize_t tx_timer_usecs_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
return sprintf(buf, "%u\n", ctx->timer_interval / (u32)NSEC_PER_USEC);
}
@@ -239,7 +239,7 @@ static ssize_t min_tx_pkt_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
unsigned long val;
/* no need to restrict values - anything from 0 to infinity is OK */
@@ -255,7 +255,7 @@ static ssize_t rx_max_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
unsigned long val;
if (kstrtoul(buf, 0, &val) || cdc_ncm_check_rx_max(dev, val) != val)
@@ -270,7 +270,7 @@ static ssize_t tx_max_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
unsigned long val;
if (kstrtoul(buf, 0, &val) || cdc_ncm_check_tx_max(dev, val) != val)
@@ -285,7 +285,7 @@ static ssize_t tx_timer_usecs_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
ssize_t ret;
unsigned long val;
@@ -311,7 +311,7 @@ static DEVICE_ATTR_RW(tx_timer_usecs);
static ssize_t ndp_to_end_show(struct device *d, struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
return sprintf(buf, "%c\n", ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END ? 'Y' : 'N');
}
@@ -319,7 +319,7 @@ static ssize_t ndp_to_end_show(struct device *d, struct device_attribute *attr,
static ssize_t ndp_to_end_store(struct device *d, struct device_attribute *attr, const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
bool enable;
if (kstrtobool(buf, &enable))
@@ -361,7 +361,7 @@ static DEVICE_ATTR_RW(ndp_to_end);
static ssize_t cdc_ncm_show_##name(struct device *d, struct device_attribute *attr, char *buf) \
{ \
struct usbnet *dev = netdev_priv(to_net_dev(d)); \
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; \
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev); \
return sprintf(buf, format "\n", tocpu(ctx->ncm_parm.name)); \
} \
static DEVICE_ATTR(name, 0444, cdc_ncm_show_##name, NULL)
@@ -404,7 +404,7 @@ static const struct attribute_group cdc_ncm_sysfs_attr_group = {
/* handle rx_max and tx_max changes */
static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
u32 val;
@@ -476,7 +476,7 @@ static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
/* helpers for NCM and MBIM differences */
static u8 cdc_ncm_flags(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting) && ctx->mbim_desc)
return ctx->mbim_desc->bmNetworkCapabilities;
@@ -501,7 +501,7 @@ static u32 cdc_ncm_min_dgram_size(struct usbnet *dev)
static u32 cdc_ncm_max_dgram_size(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting) && ctx->mbim_desc)
return le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize);
@@ -515,7 +515,7 @@ static u32 cdc_ncm_max_dgram_size(struct usbnet *dev)
*/
static int cdc_ncm_init(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
int err;
@@ -608,7 +608,7 @@ static int cdc_ncm_init(struct usbnet *dev)
/* set a new max datagram size */
static void cdc_ncm_set_dgram_size(struct usbnet *dev, int new_size)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
__le16 max_datagram_size;
u16 mbim_mtu;
@@ -656,7 +656,7 @@ static void cdc_ncm_set_dgram_size(struct usbnet *dev, int new_size)
static void cdc_ncm_fix_modulus(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
u32 val;
/*
@@ -700,7 +700,7 @@ static void cdc_ncm_fix_modulus(struct usbnet *dev)
static int cdc_ncm_setup(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
u32 def_rx, def_tx;
/* be conservative when selecting initial buffer size to
@@ -769,9 +769,6 @@ cdc_ncm_find_endpoints(struct usbnet *dev, struct usb_interface *intf)
static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
{
- if (ctx == NULL)
- return;
-
if (ctx->tx_rem_skb != NULL) {
dev_kfree_skb_any(ctx->tx_rem_skb);
ctx->tx_rem_skb = NULL;
@@ -786,8 +783,6 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
kfree(ctx->delayed_ndp16);
else
kfree(ctx->delayed_ndp32);
-
- kfree(ctx);
}
/* we need to override the usbnet change_mtu ndo for two reasons:
@@ -819,7 +814,7 @@ static const struct net_device_ops cdc_ncm_netdev_ops = {
int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags)
{
- struct cdc_ncm_ctx *ctx;
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
struct usb_driver *driver;
u8 *buf;
int len;
@@ -827,10 +822,6 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
u8 iface_no;
struct usb_cdc_parsed_header hdr;
- ctx = kzalloc_obj(*ctx);
- if (!ctx)
- return -ENOMEM;
-
ctx->dev = dev;
hrtimer_setup(&ctx->tx_timer, &cdc_ncm_tx_timer_cb, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
@@ -838,9 +829,6 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
atomic_set(&ctx->stop, 0);
spin_lock_init(&ctx->mtx);
- /* store ctx pointer in device data field */
- dev->data[0] = (unsigned long)ctx;
-
/* only the control interface can be successfully probed */
ctx->control = intf;
@@ -988,8 +976,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
if (ctx->data != ctx->control)
usb_driver_release_interface(driver, ctx->data);
error:
- cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);
- dev->data[0] = 0;
+ cdc_ncm_free(usbnet_priv(dev));
dev_info(&intf->dev, "bind() failure\n");
return -ENODEV;
}
@@ -997,12 +984,9 @@ EXPORT_SYMBOL_GPL(cdc_ncm_bind_common);
void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
struct usb_driver *driver = driver_of(intf);
- if (ctx == NULL)
- return; /* no setup */
-
atomic_set(&ctx->stop, 1);
hrtimer_cancel(&ctx->tx_timer);
@@ -1203,7 +1187,7 @@ static struct usb_cdc_ncm_ndp32 *cdc_ncm_ndp32(struct cdc_ncm_ctx *ctx, struct s
struct sk_buff *
cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
union {
struct usb_cdc_ncm_nth16 *nth16;
struct usb_cdc_ncm_nth32 *nth32;
@@ -1523,7 +1507,7 @@ struct sk_buff *
cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
struct sk_buff *skb_out;
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
/*
* The Ethernet API we are using does not support transmitting
@@ -1725,7 +1709,7 @@ EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_ndp32);
int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
{
struct sk_buff *skb;
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
unsigned int len;
int nframes;
int x;
@@ -1904,7 +1888,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
static void cdc_ncm_update_filter(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = usbnet_priv(dev);
if (ctx->filtering_supported)
usbnet_cdc_update_filter(dev);
@@ -1921,6 +1905,7 @@ static const struct driver_info cdc_ncm_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = cdc_ncm_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as cdc_ncm_info, but with FLAG_SEND_ZLP */
@@ -1935,6 +1920,7 @@ static const struct driver_info cdc_ncm_zlp_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = cdc_ncm_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as cdc_ncm_info, but with FLAG_SEND_ZLP */
@@ -1949,6 +1935,7 @@ static const struct driver_info apple_tethering_interface_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = usbnet_cdc_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as apple_tethering_interface_info, but without FLAG_LINK_INTR */
@@ -1963,6 +1950,7 @@ static const struct driver_info apple_private_interface_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = usbnet_cdc_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as cdc_ncm_info, but with FLAG_WWAN */
@@ -1977,6 +1965,7 @@ static const struct driver_info wwan_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = cdc_ncm_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as wwan_info, but with FLAG_NOARP */
@@ -1991,6 +1980,7 @@ static const struct driver_info wwan_noarp_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = cdc_ncm_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
static const struct usb_device_id cdc_devs[] = {
--
2.53.0
next prev parent reply other threads:[~2026-03-03 14:53 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-03 14:50 [RFCv2 01/13] net: usb: usbnet: use proper ep number macros Oliver Neukum
2026-03-03 14:50 ` [RFCv2 02/13] net: usb: move updating filter and status from cdc to usbnet Oliver Neukum
2026-03-03 14:50 ` [RFCv2 03/13] net: usb: centralize usbnet_cdc_zte_rx_fixup in usbnet Oliver Neukum
2026-03-03 14:50 ` [RFCv2 04/13] net: usb: usbnet: add access helper for private data Oliver Neukum
2026-03-03 14:50 ` [RFCv2 05/13] net: usb: use accessor helper for usbnet " Oliver Neukum
2026-03-03 14:50 ` [RFCv2 06/13] net: usb: usbnet: add cdc_state to struct usbnet Oliver Neukum
2026-03-03 14:50 ` [RFCv2 07/13] net: usb: use cdc_state in " Oliver Neukum
2026-03-03 14:50 ` [RFCv2 08/13] net: usb: usbnet: allow drivers to specify private space needed Oliver Neukum
2026-03-03 14:50 ` [RFCv2 09/13] net: usb: use allocation on demand for usbnet Oliver Neukum
2026-03-03 14:50 ` [RFCv2 10/13] net: usb: sierra_net: use dynamic private allocation Oliver Neukum
2026-03-03 14:50 ` Oliver Neukum [this message]
2026-03-03 14:50 ` [RFCv2 12/13] net: usb: smsc95xx: " Oliver Neukum
2026-03-03 14:50 ` [RFCv2 13/13] net: usb: lg-vl600: " Oliver Neukum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260303145242.1377514-11-oneukum@suse.com \
--to=oneukum@suse.com \
--cc=andrew@lunn.ch \
--cc=bjorn@mork.no \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox