qmi-wwan: use common parser

This moves qmi-wwan to the common parser for CDC user
to reduce code duplication.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 355842b..4752e69 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -229,11 +229,11 @@
 	u8 *buf = intf->cur_altsetting->extra;
 	int len = intf->cur_altsetting->extralen;
 	struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
-	struct usb_cdc_union_desc *cdc_union = NULL;
-	struct usb_cdc_ether_desc *cdc_ether = NULL;
-	u32 found = 0;
+	struct usb_cdc_union_desc *cdc_union;
+	struct usb_cdc_ether_desc *cdc_ether;
 	struct usb_driver *driver = driver_of(intf);
 	struct qmi_wwan_state *info = (void *)&dev->data;
+	struct usb_cdc_parsed_header hdr;
 
 	BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) <
 		      sizeof(struct qmi_wwan_state)));
@@ -243,63 +243,9 @@
 	info->data = intf;
 
 	/* and a number of CDC descriptors */
-	while (len > 3) {
-		struct usb_descriptor_header *h = (void *)buf;
-
-		/* ignore any misplaced descriptors */
-		if (h->bDescriptorType != USB_DT_CS_INTERFACE)
-			goto next_desc;
-
-		/* buf[2] is CDC descriptor subtype */
-		switch (buf[2]) {
-		case USB_CDC_HEADER_TYPE:
-			if (found & 1 << USB_CDC_HEADER_TYPE) {
-				dev_dbg(&intf->dev, "extra CDC header\n");
-				goto err;
-			}
-			if (h->bLength != sizeof(struct usb_cdc_header_desc)) {
-				dev_dbg(&intf->dev, "CDC header len %u\n",
-					h->bLength);
-				goto err;
-			}
-			break;
-		case USB_CDC_UNION_TYPE:
-			if (found & 1 << USB_CDC_UNION_TYPE) {
-				dev_dbg(&intf->dev, "extra CDC union\n");
-				goto err;
-			}
-			if (h->bLength != sizeof(struct usb_cdc_union_desc)) {
-				dev_dbg(&intf->dev, "CDC union len %u\n",
-					h->bLength);
-				goto err;
-			}
-			cdc_union = (struct usb_cdc_union_desc *)buf;
-			break;
-		case USB_CDC_ETHERNET_TYPE:
-			if (found & 1 << USB_CDC_ETHERNET_TYPE) {
-				dev_dbg(&intf->dev, "extra CDC ether\n");
-				goto err;
-			}
-			if (h->bLength != sizeof(struct usb_cdc_ether_desc)) {
-				dev_dbg(&intf->dev, "CDC ether len %u\n",
-					h->bLength);
-				goto err;
-			}
-			cdc_ether = (struct usb_cdc_ether_desc *)buf;
-			break;
-		}
-
-		/* Remember which CDC functional descriptors we've seen.  Works
-		 * for all types we care about, of which USB_CDC_ETHERNET_TYPE
-		 * (0x0f) is the highest numbered
-		 */
-		if (buf[2] < 32)
-			found |= 1 << buf[2];
-
-next_desc:
-		len -= h->bLength;
-		buf += h->bLength;
-	}
+	cdc_parse_cdc_header(&hdr, intf, buf, len);
+	cdc_union = hdr.usb_cdc_union_desc;
+	cdc_ether = hdr.usb_cdc_ether_desc;
 
 	/* Use separate control and data interfaces if we found a CDC Union */
 	if (cdc_union) {