diff mbox

[net-next,21/24] net: cdc_ncm: refactoring cdc_ncm_setup

Message ID 1383301021-16613-22-git-send-email-bjorn@mork.no
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Bjørn Mork Nov. 1, 2013, 10:16 a.m. UTC
Rewriting the "set max datagram" part of dc_ncm_setup to
separate the selection and validatation of the size from
the code which optionally informs the device of this
value.  This ensures that we use the correct value
regardless of device support for the get and set commands.

Removing some of the many indent levels while doing this
to make the code more readable.

Cc: Alexey Orishko <alexey.orishko@gmail.com>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 drivers/net/usb/cdc_ncm.c |  108 ++++++++++++++++++---------------------------
 1 file changed, 44 insertions(+), 64 deletions(-)
diff mbox

Patch

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 83e6d5b..62dcb2e 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;
 }