Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d1c4310 authored by Greg Suarez's avatar Greg Suarez Committed by David S. Miller
Browse files

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: default avatarGreg Suarez <gsuarez@smithmicro.com>
Signed-off-by: default avatarBjørn Mork <bjorn@mork.no>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 51615edd
Loading
Loading
Loading
Loading
+35 −15
Original line number Diff line number Diff line
@@ -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 */
@@ -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;
@@ -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;

@@ -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 "
@@ -237,7 +253,7 @@ size_err:

	/* 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);
@@ -279,7 +295,7 @@ size_err:
	}

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

	/* additional configuration */
@@ -307,12 +323,18 @@ size_err:
			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);
@@ -329,7 +351,7 @@ size_err:
				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);
@@ -338,12 +360,10 @@ size_err:
					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 !=
@@ -364,8 +384,8 @@ size_err:
	}

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;
}