diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 83e6d5ba962aa8b454bc91f481a9f4e9f7531328..62dcb2e11e0b9d0c3ade16488ab5d5fde067bd44 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -76,8 +76,7 @@ static u8 cdc_ncm_setup(struct usbnet *dev)
 	int err;
 	int eth_hlen;
 	u16 ntb_fmt_supported;
-	u32 min_dgram_size;
-	u32 min_hdr_size;
+	__le16 max_datagram_size;
 
 	iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
 
@@ -101,20 +100,29 @@ static u8 cdc_ncm_setup(struct usbnet *dev)
 	ctx->tx_max_datagrams = le16_to_cpu(ncm_parm.wNtbOutMaxDatagrams);
 	ntb_fmt_supported = le16_to_cpu(ncm_parm.bmNtbFormatsSupported);
 
-	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;
+	/* there are some minor differences in NCM and MBIM defaults */
+	if (cdc_ncm_comm_intf_is_mbim(ctx->control->cur_altsetting)) {
+		if (!ctx->mbim_desc)
+			return -EINVAL;
 		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;
+		flags = ctx->mbim_desc->bmNetworkCapabilities;
+		ctx->max_datagram_size = le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize);
+		if (ctx->max_datagram_size < CDC_MBIM_MIN_DATAGRAM_SIZE)
+			ctx->max_datagram_size = CDC_MBIM_MIN_DATAGRAM_SIZE;
 	} else {
-		flags = 0;
+		if (!ctx->func_desc)
+			return -EINVAL;
+		eth_hlen = ETH_HLEN;
+		flags = ctx->func_desc->bmNetworkCapabilities;
+		ctx->max_datagram_size = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
+		if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
+			ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
 	}
 
+	/* common absolute max for NCM and MBIM */
+	if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
+		ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE;
+
 	dev_dbg(&dev->intf->dev,
 		"dwNtbInMaxSize=%u dwNtbOutMaxSize=%u wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u wNdpOutAlignment=%u wNtbOutMaxDatagrams=%u flags=0x%x\n",
 		ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus,
@@ -151,8 +159,7 @@ static u8 cdc_ncm_setup(struct usbnet *dev)
 	}
 
 	/* verify maximum size of transmitted NTB in bytes */
-	if ((ctx->tx_max <
-	    (min_hdr_size + min_dgram_size)) ||
+	if ((ctx->tx_max < (CDC_NCM_MIN_HDR_SIZE + ctx->max_datagram_size)) ||
 	    (ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX)) {
 		dev_dbg(&dev->intf->dev, "Using default maximum transmit length=%d\n",
 			CDC_NCM_NTB_MAX_SIZE_TX);
@@ -229,60 +236,33 @@ static u8 cdc_ncm_setup(struct usbnet *dev)
 			dev_dbg(&dev->intf->dev, "Setting NTB format to 16-bit failed\n");
 	}
 
-	ctx->max_datagram_size = min_dgram_size;
+	/* inform the device about the selected Max Datagram Size */
+	if (!(flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE))
+		goto out;
 
-	/* set Max Datagram Size (MTU) */
-	if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) {
-		__le16 max_datagram_size;
-		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;
-
-		err = usbnet_read_cmd(dev, USB_CDC_GET_MAX_DATAGRAM_SIZE,
-				      USB_TYPE_CLASS | USB_DIR_IN
-				      | USB_RECIP_INTERFACE,
-				      0, iface_no, &max_datagram_size, 2);
-		if (err < 0) {
-			dev_dbg(&dev->intf->dev, "GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
-				min_dgram_size);
-		} else {
-			ctx->max_datagram_size =
-				le16_to_cpu(max_datagram_size);
-			/* Check Eth descriptor value */
-			if (ctx->max_datagram_size > eth_max_sz)
-					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;
-
-			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 !=
-					le16_to_cpu(max_datagram_size)) {
-				max_datagram_size = cpu_to_le16(ctx->max_datagram_size);
-				err = usbnet_write_cmd(dev,
-						USB_CDC_SET_MAX_DATAGRAM_SIZE,
-						USB_TYPE_CLASS | USB_DIR_OUT
-						 | USB_RECIP_INTERFACE,
-						0,
-						iface_no, &max_datagram_size,
-						2);
-				if (err < 0)
-					dev_dbg(&dev->intf->dev, "SET_MAX_DGRAM_SIZE failed\n");
-			}
-		}
+	/* read current mtu value from device */
+	err = usbnet_read_cmd(dev, USB_CDC_GET_MAX_DATAGRAM_SIZE,
+			      USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+			      0, iface_no, &max_datagram_size, 2);
+	if (err < 0) {
+		dev_dbg(&dev->intf->dev, "GET_MAX_DATAGRAM_SIZE failed\n");
+		goto out;
 	}
 
-max_dgram_err:
-	if (dev->net->mtu != (ctx->max_datagram_size - eth_hlen))
-		dev->net->mtu = ctx->max_datagram_size - eth_hlen;
+	if (le16_to_cpu(max_datagram_size) == ctx->max_datagram_size)
+		goto out;
+
+	max_datagram_size = cpu_to_le16(ctx->max_datagram_size);
+	err = usbnet_write_cmd(dev, USB_CDC_SET_MAX_DATAGRAM_SIZE,
+			       USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE,
+			       0, iface_no, &max_datagram_size, 2);
+	if (err < 0)
+		dev_dbg(&dev->intf->dev, "SET_MAX_DATAGRAM_SIZE failed\n");
 
+out:
+	/* set MTU to max supported by the device if necessary */
+	if (dev->net->mtu > ctx->max_datagram_size - eth_hlen)
+		dev->net->mtu = ctx->max_datagram_size - eth_hlen;
 	return 0;
 }