Skip to content

Commit

Permalink
net: cdc_ncm: adding MBIM support to ncm_setup
Browse files Browse the repository at this point in the history
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 <gsuarez@smithmicro.com>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Greg Suarez authored and David S. Miller committed Oct 23, 2012
1 parent 51615ed commit 2d1c431
Showing 1 changed file with 35 additions and 15 deletions.
50 changes: 35 additions & 15 deletions drivers/net/usb/cdc_ncm.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
#define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */

/* Minimum value for MaxDatagramSize, ch. 8.1.3 */
#define CDC_MBIM_MIN_DATAGRAM_SIZE 2048 /* bytes */

#define CDC_NCM_MIN_TX_PKT 512 /* bytes */

/* Default value for MaxDatagramSize */
Expand Down Expand Up @@ -98,6 +101,7 @@ struct cdc_ncm_ctx {
struct tasklet_struct bh;

const struct usb_cdc_ncm_desc *func_desc;
const struct usb_cdc_mbim_desc *mbim_desc;
const struct usb_cdc_header_desc *header_desc;
const struct usb_cdc_union_desc *union_desc;
const struct usb_cdc_ether_desc *ether_desc;
Expand Down Expand Up @@ -158,7 +162,10 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
u8 flags;
u8 iface_no;
int err;
int eth_hlen;
u16 ntb_fmt_supported;
u32 min_dgram_size;
u32 min_hdr_size;

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

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

if (ctx->func_desc != NULL)
eth_hlen = ETH_HLEN;
min_dgram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
min_hdr_size = CDC_NCM_MIN_HDR_SIZE;
if (ctx->mbim_desc != NULL) {
flags = ctx->mbim_desc->bmNetworkCapabilities;
eth_hlen = 0;
min_dgram_size = CDC_MBIM_MIN_DATAGRAM_SIZE;
min_hdr_size = 0;
} else if (ctx->func_desc != NULL) {
flags = ctx->func_desc->bmNetworkCapabilities;
else
} else {
flags = 0;
}

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

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

/* adjust TX-remainder according to NCM specification. */
ctx->tx_remainder = ((ctx->tx_remainder - ETH_HLEN) &
(ctx->tx_modulus - 1));
ctx->tx_remainder = ((ctx->tx_remainder - eth_hlen) &
(ctx->tx_modulus - 1));

/* additional configuration */

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

ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
ctx->max_datagram_size = min_dgram_size;

/* set Max Datagram Size (MTU) */
if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) {
__le16 *max_datagram_size;
u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
u16 eth_max_sz;
if (ctx->ether_desc != NULL)
eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
else if (ctx->mbim_desc != NULL)
eth_max_sz = le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize);
else
goto max_dgram_err;

max_datagram_size = kzalloc(sizeof(*max_datagram_size),
GFP_KERNEL);
Expand All @@ -329,7 +351,7 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
2, 1000);
if (err < 0) {
pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
CDC_NCM_MIN_DATAGRAM_SIZE);
min_dgram_size);
} else {
ctx->max_datagram_size =
le16_to_cpu(*max_datagram_size);
Expand All @@ -338,12 +360,10 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
ctx->max_datagram_size = eth_max_sz;

if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
ctx->max_datagram_size =
CDC_NCM_MAX_DATAGRAM_SIZE;
ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE;

if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
ctx->max_datagram_size =
CDC_NCM_MIN_DATAGRAM_SIZE;
if (ctx->max_datagram_size < min_dgram_size)
ctx->max_datagram_size = min_dgram_size;

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

max_dgram_err:
if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN))
ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN;
if (ctx->netdev->mtu != (ctx->max_datagram_size - eth_hlen))
ctx->netdev->mtu = ctx->max_datagram_size - eth_hlen;

return 0;
}
Expand Down

0 comments on commit 2d1c431

Please sign in to comment.