Skip to content

Commit 2d1c431

Browse files
Greg Suarezdavem330
authored andcommitted
net: cdc_ncm: adding MBIM support to ncm_setup
MBIM and NCM are very similar, so we can reuse most of the setup and bind logic in cdc_ncm for CDC MBIM devices. Handle a few minor differences in ncm_setup. Signed-off-by: Greg Suarez <[email protected]> Signed-off-by: Bjørn Mork <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 51615ed commit 2d1c431

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed

drivers/net/usb/cdc_ncm.c

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
6565
#define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */
6666

67+
/* Minimum value for MaxDatagramSize, ch. 8.1.3 */
68+
#define CDC_MBIM_MIN_DATAGRAM_SIZE 2048 /* bytes */
69+
6770
#define CDC_NCM_MIN_TX_PKT 512 /* bytes */
6871

6972
/* Default value for MaxDatagramSize */
@@ -98,6 +101,7 @@ struct cdc_ncm_ctx {
98101
struct tasklet_struct bh;
99102

100103
const struct usb_cdc_ncm_desc *func_desc;
104+
const struct usb_cdc_mbim_desc *mbim_desc;
101105
const struct usb_cdc_header_desc *header_desc;
102106
const struct usb_cdc_union_desc *union_desc;
103107
const struct usb_cdc_ether_desc *ether_desc;
@@ -158,7 +162,10 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
158162
u8 flags;
159163
u8 iface_no;
160164
int err;
165+
int eth_hlen;
161166
u16 ntb_fmt_supported;
167+
u32 min_dgram_size;
168+
u32 min_hdr_size;
162169

163170
iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
164171

@@ -184,10 +191,19 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
184191
ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams);
185192
ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported);
186193

187-
if (ctx->func_desc != NULL)
194+
eth_hlen = ETH_HLEN;
195+
min_dgram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
196+
min_hdr_size = CDC_NCM_MIN_HDR_SIZE;
197+
if (ctx->mbim_desc != NULL) {
198+
flags = ctx->mbim_desc->bmNetworkCapabilities;
199+
eth_hlen = 0;
200+
min_dgram_size = CDC_MBIM_MIN_DATAGRAM_SIZE;
201+
min_hdr_size = 0;
202+
} else if (ctx->func_desc != NULL) {
188203
flags = ctx->func_desc->bmNetworkCapabilities;
189-
else
204+
} else {
190205
flags = 0;
206+
}
191207

192208
pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u "
193209
"wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u "
@@ -237,7 +253,7 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
237253

238254
/* verify maximum size of transmitted NTB in bytes */
239255
if ((ctx->tx_max <
240-
(CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) ||
256+
(min_hdr_size + min_dgram_size)) ||
241257
(ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX)) {
242258
pr_debug("Using default maximum transmit length=%d\n",
243259
CDC_NCM_NTB_MAX_SIZE_TX);
@@ -279,8 +295,8 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
279295
}
280296

281297
/* adjust TX-remainder according to NCM specification. */
282-
ctx->tx_remainder = ((ctx->tx_remainder - ETH_HLEN) &
283-
(ctx->tx_modulus - 1));
298+
ctx->tx_remainder = ((ctx->tx_remainder - eth_hlen) &
299+
(ctx->tx_modulus - 1));
284300

285301
/* additional configuration */
286302

@@ -307,12 +323,18 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
307323
pr_debug("Setting NTB format to 16-bit failed\n");
308324
}
309325

310-
ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
326+
ctx->max_datagram_size = min_dgram_size;
311327

312328
/* set Max Datagram Size (MTU) */
313329
if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) {
314330
__le16 *max_datagram_size;
315-
u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
331+
u16 eth_max_sz;
332+
if (ctx->ether_desc != NULL)
333+
eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
334+
else if (ctx->mbim_desc != NULL)
335+
eth_max_sz = le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize);
336+
else
337+
goto max_dgram_err;
316338

317339
max_datagram_size = kzalloc(sizeof(*max_datagram_size),
318340
GFP_KERNEL);
@@ -329,7 +351,7 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
329351
2, 1000);
330352
if (err < 0) {
331353
pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
332-
CDC_NCM_MIN_DATAGRAM_SIZE);
354+
min_dgram_size);
333355
} else {
334356
ctx->max_datagram_size =
335357
le16_to_cpu(*max_datagram_size);
@@ -338,12 +360,10 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
338360
ctx->max_datagram_size = eth_max_sz;
339361

340362
if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
341-
ctx->max_datagram_size =
342-
CDC_NCM_MAX_DATAGRAM_SIZE;
363+
ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE;
343364

344-
if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
345-
ctx->max_datagram_size =
346-
CDC_NCM_MIN_DATAGRAM_SIZE;
365+
if (ctx->max_datagram_size < min_dgram_size)
366+
ctx->max_datagram_size = min_dgram_size;
347367

348368
/* if value changed, update device */
349369
if (ctx->max_datagram_size !=
@@ -364,8 +384,8 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
364384
}
365385

366386
max_dgram_err:
367-
if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN))
368-
ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN;
387+
if (ctx->netdev->mtu != (ctx->max_datagram_size - eth_hlen))
388+
ctx->netdev->mtu = ctx->max_datagram_size - eth_hlen;
369389

370390
return 0;
371391
}

0 commit comments

Comments
 (0)