Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * Copyright (c) 2012  Bjørn Mork <bjorn@mork.no>
  3 *
  4 * This program is free software; you can redistribute it and/or
  5 * modify it under the terms of the GNU General Public License
  6 * version 2 as published by the Free Software Foundation.
  7 */
  8
  9#include <linux/module.h>
 10#include <linux/netdevice.h>
 11#include <linux/ethtool.h>
 12#include <linux/mii.h>
 13#include <linux/usb.h>
 14#include <linux/usb/cdc.h>
 15#include <linux/usb/usbnet.h>
 16#include <linux/usb/cdc-wdm.h>
 17
 18/* The name of the CDC Device Management driver */
 19#define DM_DRIVER "cdc_wdm"
 20
 21/*
 22 * This driver supports wwan (3G/LTE/?) devices using a vendor
 23 * specific management protocol called Qualcomm MSM Interface (QMI) -
 24 * in addition to the more common AT commands over serial interface
 25 * management
 26 *
 27 * QMI is wrapped in CDC, using CDC encapsulated commands on the
 28 * control ("master") interface of a two-interface CDC Union
 29 * resembling standard CDC ECM.  The devices do not use the control
 30 * interface for any other CDC messages.  Most likely because the
 31 * management protocol is used in place of the standard CDC
 32 * notifications NOTIFY_NETWORK_CONNECTION and NOTIFY_SPEED_CHANGE
 33 *
 34 * Handling a protocol like QMI is out of the scope for any driver.
 35 * It can be exported as a character device using the cdc-wdm driver,
 36 * which will enable userspace applications ("modem managers") to
 37 * handle it.  This may be required to use the network interface
 38 * provided by the driver.
 39 *
 40 * These devices may alternatively/additionally be configured using AT
 41 * commands on any of the serial interfaces driven by the option driver
 42 *
 43 * This driver binds only to the data ("slave") interface to enable
 44 * the cdc-wdm driver to bind to the control interface.  It still
 45 * parses the CDC functional descriptors on the control interface to
 46 *  a) verify that this is indeed a handled interface (CDC Union
 47 *     header lists it as slave)
 48 *  b) get MAC address and other ethernet config from the CDC Ethernet
 49 *     header
 50 *  c) enable user bind requests against the control interface, which
 51 *     is the common way to bind to CDC Ethernet Control Model type
 52 *     interfaces
 53 *  d) provide a hint to the user about which interface is the
 54 *     corresponding management interface
 55 */
 56
 57static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
 58{
 59	int status = -1;
 60	struct usb_interface *control = NULL;
 61	u8 *buf = intf->cur_altsetting->extra;
 62	int len = intf->cur_altsetting->extralen;
 63	struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
 64	struct usb_cdc_union_desc *cdc_union = NULL;
 65	struct usb_cdc_ether_desc *cdc_ether = NULL;
 66	u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE;
 67	u32 found = 0;
 68	atomic_t *pmcount = (void *)&dev->data[1];
 69
 70	atomic_set(pmcount, 0);
 71
 72	/*
 73	 * assume a data interface has no additional descriptors and
 74	 * that the control and data interface are numbered
 75	 * consecutively - this holds for the Huawei device at least
 76	 */
 77	if (len == 0 && desc->bInterfaceNumber > 0) {
 78		control = usb_ifnum_to_if(dev->udev, desc->bInterfaceNumber - 1);
 79		if (!control)
 80			goto err;
 81
 82		buf = control->cur_altsetting->extra;
 83		len = control->cur_altsetting->extralen;
 84		dev_dbg(&intf->dev, "guessing \"control\" => %s, \"data\" => this\n",
 85			dev_name(&control->dev));
 86	}
 87
 88	while (len > 3) {
 89		struct usb_descriptor_header *h = (void *)buf;
 90
 91		/* ignore any misplaced descriptors */
 92		if (h->bDescriptorType != USB_DT_CS_INTERFACE)
 93			goto next_desc;
 94
 95		/* buf[2] is CDC descriptor subtype */
 96		switch (buf[2]) {
 97		case USB_CDC_HEADER_TYPE:
 98			if (found & 1 << USB_CDC_HEADER_TYPE) {
 99				dev_dbg(&intf->dev, "extra CDC header\n");
100				goto err;
101			}
102			if (h->bLength != sizeof(struct usb_cdc_header_desc)) {
103				dev_dbg(&intf->dev, "CDC header len %u\n", h->bLength);
104				goto err;
105			}
106			break;
107		case USB_CDC_UNION_TYPE:
108			if (found & 1 << USB_CDC_UNION_TYPE) {
109				dev_dbg(&intf->dev, "extra CDC union\n");
110				goto err;
111			}
112			if (h->bLength != sizeof(struct usb_cdc_union_desc)) {
113				dev_dbg(&intf->dev, "CDC union len %u\n", h->bLength);
114				goto err;
115			}
116			cdc_union = (struct usb_cdc_union_desc *)buf;
117			break;
118		case USB_CDC_ETHERNET_TYPE:
119			if (found & 1 << USB_CDC_ETHERNET_TYPE) {
120				dev_dbg(&intf->dev, "extra CDC ether\n");
121				goto err;
122			}
123			if (h->bLength != sizeof(struct usb_cdc_ether_desc)) {
124				dev_dbg(&intf->dev, "CDC ether len %u\n",  h->bLength);
125				goto err;
126			}
127			cdc_ether = (struct usb_cdc_ether_desc *)buf;
128			break;
129		}
130
131		/*
132		 * Remember which CDC functional descriptors we've seen.  Works
133		 * for all types we care about, of which USB_CDC_ETHERNET_TYPE
134		 * (0x0f) is the highest numbered
135		 */
136		if (buf[2] < 32)
137			found |= 1 << buf[2];
138
139next_desc:
140		len -= h->bLength;
141		buf += h->bLength;
142	}
143
144	/* did we find all the required ones? */
145	if ((found & required) != required) {
146		dev_err(&intf->dev, "CDC functional descriptors missing\n");
147		goto err;
148	}
149
150	/* give the user a helpful hint if trying to bind to the wrong interface */
151	if (cdc_union && desc->bInterfaceNumber == cdc_union->bMasterInterface0) {
152		dev_err(&intf->dev, "leaving \"control\" interface for " DM_DRIVER " - try binding to %s instead!\n",
153			dev_name(&usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0)->dev));
154		goto err;
155	}
156
157	/* errors aren't fatal - we can live with the dynamic address */
158	if (cdc_ether) {
159		dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize);
160		usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress);
161	}
162
163	/* success! point the user to the management interface */
164	if (control)
165		dev_info(&intf->dev, "Use \"" DM_DRIVER "\" for QMI interface %s\n",
166			dev_name(&control->dev));
167
168	/* XXX: add a sysfs symlink somewhere to help management applications find it? */
169
170	/* collect bulk endpoints now that we know intf == "data" interface */
171	status = usbnet_get_endpoints(dev, intf);
172
173err:
174	return status;
175}
176
177/* using a counter to merge subdriver requests with our own into a combined state */
178static int qmi_wwan_manage_power(struct usbnet *dev, int on)
179{
180	atomic_t *pmcount = (void *)&dev->data[1];
181	int rv = 0;
182
183	dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(pmcount), on);
184
185	if ((on && atomic_add_return(1, pmcount) == 1) || (!on && atomic_dec_and_test(pmcount))) {
186		/* need autopm_get/put here to ensure the usbcore sees the new value */
187		rv = usb_autopm_get_interface(dev->intf);
188		if (rv < 0)
189			goto err;
190		dev->intf->needs_remote_wakeup = on;
191		usb_autopm_put_interface(dev->intf);
192	}
193err:
194	return rv;
195}
196
197static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on)
198{
199	struct usbnet *dev = usb_get_intfdata(intf);
200
201	/* can be called while disconnecting */
202	if (!dev)
203		return 0;
204	return qmi_wwan_manage_power(dev, on);
205}
206
207/* Some devices combine the "control" and "data" functions into a
208 * single interface with all three endpoints: interrupt + bulk in and
209 * out
210 *
211 * Setting up cdc-wdm as a subdriver owning the interrupt endpoint
212 * will let it provide userspace access to the encapsulated QMI
213 * protocol without interfering with the usbnet operations.
214  */
215static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf)
216{
217	int rv;
218	struct usb_driver *subdriver = NULL;
219	atomic_t *pmcount = (void *)&dev->data[1];
220
221	/* ZTE makes devices where the interface descriptors and endpoint
222	 * configurations of two or more interfaces are identical, even
223	 * though the functions are completely different.  If set, then
224	 * driver_info->data is a bitmap of acceptable interface numbers
225	 * allowing us to bind to one such interface without binding to
226	 * all of them
227	 */
228	if (dev->driver_info->data &&
229	    !test_bit(intf->cur_altsetting->desc.bInterfaceNumber, &dev->driver_info->data)) {
230		dev_info(&intf->dev, "not on our whitelist - ignored");
231		rv = -ENODEV;
232		goto err;
233	}
234
235	atomic_set(pmcount, 0);
236
237	/* collect all three endpoints */
238	rv = usbnet_get_endpoints(dev, intf);
239	if (rv < 0)
240		goto err;
241
242	/* require interrupt endpoint for subdriver */
243	if (!dev->status) {
244		rv = -EINVAL;
245		goto err;
246	}
247
248	subdriver = usb_cdc_wdm_register(intf, &dev->status->desc, 512, &qmi_wwan_cdc_wdm_manage_power);
249	if (IS_ERR(subdriver)) {
250		rv = PTR_ERR(subdriver);
251		goto err;
252	}
253
254	/* can't let usbnet use the interrupt endpoint */
255	dev->status = NULL;
256
257	/* save subdriver struct for suspend/resume wrappers */
258	dev->data[0] = (unsigned long)subdriver;
259
260err:
261	return rv;
262}
263
264static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf)
265{
266	struct usb_driver *subdriver = (void *)dev->data[0];
267
268	if (subdriver && subdriver->disconnect)
269		subdriver->disconnect(intf);
270
271	dev->data[0] = (unsigned long)NULL;
272}
273
274/* suspend/resume wrappers calling both usbnet and the cdc-wdm
275 * subdriver if present.
276 *
277 * NOTE: cdc-wdm also supports pre/post_reset, but we cannot provide
278 * wrappers for those without adding usbnet reset support first.
279 */
280static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message)
281{
282	struct usbnet *dev = usb_get_intfdata(intf);
283	struct usb_driver *subdriver = (void *)dev->data[0];
284	int ret;
285
286	ret = usbnet_suspend(intf, message);
287	if (ret < 0)
288		goto err;
289
290	if (subdriver && subdriver->suspend)
291		ret = subdriver->suspend(intf, message);
292	if (ret < 0)
293		usbnet_resume(intf);
294err:
295	return ret;
296}
297
298static int qmi_wwan_resume(struct usb_interface *intf)
299{
300	struct usbnet *dev = usb_get_intfdata(intf);
301	struct usb_driver *subdriver = (void *)dev->data[0];
302	int ret = 0;
303
304	if (subdriver && subdriver->resume)
305		ret = subdriver->resume(intf);
306	if (ret < 0)
307		goto err;
308	ret = usbnet_resume(intf);
309	if (ret < 0 && subdriver && subdriver->resume && subdriver->suspend)
310		subdriver->suspend(intf, PMSG_SUSPEND);
311err:
312	return ret;
313}
314
315
316static const struct driver_info	qmi_wwan_info = {
317	.description	= "QMI speaking wwan device",
318	.flags		= FLAG_WWAN,
319	.bind		= qmi_wwan_bind,
320	.manage_power	= qmi_wwan_manage_power,
321};
322
323static const struct driver_info	qmi_wwan_shared = {
324	.description	= "QMI speaking wwan device with combined interface",
325	.flags		= FLAG_WWAN,
326	.bind		= qmi_wwan_bind_shared,
327	.unbind		= qmi_wwan_unbind_shared,
328	.manage_power	= qmi_wwan_manage_power,
329};
330
331static const struct driver_info	qmi_wwan_force_int0 = {
332	.description	= "Qualcomm WWAN/QMI device",
333	.flags		= FLAG_WWAN,
334	.bind		= qmi_wwan_bind_shared,
335	.unbind		= qmi_wwan_unbind_shared,
336	.manage_power	= qmi_wwan_manage_power,
337	.data		= BIT(0), /* interface whitelist bitmap */
338};
339
340static const struct driver_info	qmi_wwan_force_int1 = {
341	.description	= "Qualcomm WWAN/QMI device",
342	.flags		= FLAG_WWAN,
343	.bind		= qmi_wwan_bind_shared,
344	.unbind		= qmi_wwan_unbind_shared,
345	.manage_power	= qmi_wwan_manage_power,
346	.data		= BIT(1), /* interface whitelist bitmap */
347};
348
349static const struct driver_info qmi_wwan_force_int2 = {
350	.description	= "Qualcomm WWAN/QMI device",
351	.flags		= FLAG_WWAN,
352	.bind		= qmi_wwan_bind_shared,
353	.unbind		= qmi_wwan_unbind_shared,
354	.manage_power	= qmi_wwan_manage_power,
355	.data		= BIT(2), /* interface whitelist bitmap */
356};
357
358static const struct driver_info	qmi_wwan_force_int3 = {
359	.description	= "Qualcomm WWAN/QMI device",
360	.flags		= FLAG_WWAN,
361	.bind		= qmi_wwan_bind_shared,
362	.unbind		= qmi_wwan_unbind_shared,
363	.manage_power	= qmi_wwan_manage_power,
364	.data		= BIT(3), /* interface whitelist bitmap */
365};
366
367static const struct driver_info	qmi_wwan_force_int4 = {
368	.description	= "Qualcomm WWAN/QMI device",
369	.flags		= FLAG_WWAN,
370	.bind		= qmi_wwan_bind_shared,
371	.unbind		= qmi_wwan_unbind_shared,
372	.manage_power	= qmi_wwan_manage_power,
373	.data		= BIT(4), /* interface whitelist bitmap */
374};
375
376/* Sierra Wireless provide equally useless interface descriptors
377 * Devices in QMI mode can be switched between two different
378 * configurations:
379 *   a) USB interface #8 is QMI/wwan
380 *   b) USB interfaces #8, #19 and #20 are QMI/wwan
381 *
382 * Both configurations provide a number of other interfaces (serial++),
383 * some of which have the same endpoint configuration as we expect, so
384 * a whitelist or blacklist is necessary.
385 *
386 * FIXME: The below whitelist should include BIT(20).  It does not
387 * because I cannot get it to work...
388 */
389static const struct driver_info	qmi_wwan_sierra = {
390	.description	= "Sierra Wireless wwan/QMI device",
391	.flags		= FLAG_WWAN,
392	.bind		= qmi_wwan_bind_shared,
393	.unbind		= qmi_wwan_unbind_shared,
394	.manage_power	= qmi_wwan_manage_power,
395	.data		= BIT(8) | BIT(19), /* interface whitelist bitmap */
396};
397
398#define HUAWEI_VENDOR_ID	0x12D1
399
400/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */
401#define QMI_GOBI1K_DEVICE(vend, prod) \
402	USB_DEVICE(vend, prod), \
403	.driver_info = (unsigned long)&qmi_wwan_force_int3
404
405/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */
406#define QMI_GOBI_DEVICE(vend, prod) \
407	USB_DEVICE(vend, prod), \
408	.driver_info = (unsigned long)&qmi_wwan_force_int0
409
410static const struct usb_device_id products[] = {
411	{	/* Huawei E392, E398 and possibly others sharing both device id and more... */
412		.match_flags        = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
413		.idVendor           = HUAWEI_VENDOR_ID,
414		.bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
415		.bInterfaceSubClass = 1,
416		.bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */
417		.driver_info        = (unsigned long)&qmi_wwan_info,
418	},
419	{	/* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */
420		.match_flags        = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
421		.idVendor           = HUAWEI_VENDOR_ID,
422		.bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
423		.bInterfaceSubClass = 1,
424		.bInterfaceProtocol = 56, /* NOTE: This is the *slave* interface of the CDC Union! */
425		.driver_info        = (unsigned long)&qmi_wwan_info,
426	},
427	{	/* Huawei E392, E398 and possibly others in "Windows mode"
428		 * using a combined control and data interface without any CDC
429		 * functional descriptors
430		 */
431		.match_flags        = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
432		.idVendor           = HUAWEI_VENDOR_ID,
433		.bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
434		.bInterfaceSubClass = 1,
435		.bInterfaceProtocol = 17,
436		.driver_info        = (unsigned long)&qmi_wwan_shared,
437	},
438	{	/* Pantech UML290 */
439		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
440		.idVendor           = 0x106c,
441		.idProduct          = 0x3718,
442		.bInterfaceClass    = 0xff,
443		.bInterfaceSubClass = 0xf0,
444		.bInterfaceProtocol = 0xff,
445		.driver_info        = (unsigned long)&qmi_wwan_shared,
446	},
447	{	/* Pantech UML290 - newer firmware */
448		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
449		.idVendor           = 0x106c,
450		.idProduct          = 0x3718,
451		.bInterfaceClass    = 0xff,
452		.bInterfaceSubClass = 0xf1,
453		.bInterfaceProtocol = 0xff,
454		.driver_info        = (unsigned long)&qmi_wwan_shared,
455	},
456	{	/* ZTE MF820D */
457		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
458		.idVendor           = 0x19d2,
459		.idProduct          = 0x0167,
460		.bInterfaceClass    = 0xff,
461		.bInterfaceSubClass = 0xff,
462		.bInterfaceProtocol = 0xff,
463		.driver_info        = (unsigned long)&qmi_wwan_force_int4,
464	},
465	{	/* ZTE MF821D */
466		.match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
467		.idVendor           = 0x19d2,
468		.idProduct          = 0x0326,
469		.bInterfaceClass    = 0xff,
470		.bInterfaceSubClass = 0xff,
471		.bInterfaceProtocol = 0xff,
472		.driver_info        = (unsigned long)&qmi_wwan_force_int4,
473	},
474	{	/* ZTE (Vodafone) K3520-Z */
475		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
476		.idVendor           = 0x19d2,
477		.idProduct          = 0x0055,
478		.bInterfaceClass    = 0xff,
479		.bInterfaceSubClass = 0xff,
480		.bInterfaceProtocol = 0xff,
481		.driver_info        = (unsigned long)&qmi_wwan_force_int1,
482	},
483	{	/* ZTE (Vodafone) K3565-Z */
484		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
485		.idVendor           = 0x19d2,
486		.idProduct          = 0x0063,
487		.bInterfaceClass    = 0xff,
488		.bInterfaceSubClass = 0xff,
489		.bInterfaceProtocol = 0xff,
490		.driver_info        = (unsigned long)&qmi_wwan_force_int4,
491	},
492	{	/* ZTE (Vodafone) K3570-Z */
493		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
494		.idVendor           = 0x19d2,
495		.idProduct          = 0x1008,
496		.bInterfaceClass    = 0xff,
497		.bInterfaceSubClass = 0xff,
498		.bInterfaceProtocol = 0xff,
499		.driver_info        = (unsigned long)&qmi_wwan_force_int4,
500	},
501	{	/* ZTE (Vodafone) K3571-Z */
502		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
503		.idVendor           = 0x19d2,
504		.idProduct          = 0x1010,
505		.bInterfaceClass    = 0xff,
506		.bInterfaceSubClass = 0xff,
507		.bInterfaceProtocol = 0xff,
508		.driver_info        = (unsigned long)&qmi_wwan_force_int4,
509	},
510	{	/* ZTE (Vodafone) K3765-Z */
511		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
512		.idVendor           = 0x19d2,
513		.idProduct          = 0x2002,
514		.bInterfaceClass    = 0xff,
515		.bInterfaceSubClass = 0xff,
516		.bInterfaceProtocol = 0xff,
517		.driver_info        = (unsigned long)&qmi_wwan_force_int4,
518	},
519	{	/* ZTE (Vodafone) K4505-Z */
520		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
521		.idVendor           = 0x19d2,
522		.idProduct          = 0x0104,
523		.bInterfaceClass    = 0xff,
524		.bInterfaceSubClass = 0xff,
525		.bInterfaceProtocol = 0xff,
526		.driver_info        = (unsigned long)&qmi_wwan_force_int4,
527	},
528	{	/* ZTE (Vodafone) K5006-Z */
529		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
530		.idVendor           = 0x19d2,
531		.idProduct          = 0x1018,
532		.bInterfaceClass    = 0xff,
533		.bInterfaceSubClass = 0xff,
534		.bInterfaceProtocol = 0xff,
535		.driver_info        = (unsigned long)&qmi_wwan_force_int3,
536	},
537	{	/* ZTE MF60 */
538		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
539		.idVendor           = 0x19d2,
540		.idProduct          = 0x1402,
541		.bInterfaceClass    = 0xff,
542		.bInterfaceSubClass = 0xff,
543		.bInterfaceProtocol = 0xff,
544		.driver_info        = (unsigned long)&qmi_wwan_force_int2,
545	},
546	{	/* Sierra Wireless MC77xx in QMI mode */
547		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
548		.idVendor           = 0x1199,
549		.idProduct          = 0x68a2,
550		.bInterfaceClass    = 0xff,
551		.bInterfaceSubClass = 0xff,
552		.bInterfaceProtocol = 0xff,
553		.driver_info        = (unsigned long)&qmi_wwan_sierra,
554	},
555	{	/* Sierra Wireless MC7700 */
556		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
557		.idVendor           = 0x0f3d,
558		.idProduct          = 0x68a2,
559		.bInterfaceClass    = 0xff,
560		.bInterfaceSubClass = 0xff,
561		.bInterfaceProtocol = 0xff,
562		.driver_info        = (unsigned long)&qmi_wwan_sierra,
563	},
564	{	/* Sierra Wireless MC7750 */
565		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
566		.idVendor           = 0x114f,
567		.idProduct          = 0x68a2,
568		.bInterfaceClass    = 0xff,
569		.bInterfaceSubClass = 0xff,
570		.bInterfaceProtocol = 0xff,
571		.driver_info        = (unsigned long)&qmi_wwan_sierra,
572	},
573	{	/* Sierra Wireless EM7700 */
574		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
575		.idVendor           = 0x1199,
576		.idProduct          = 0x901c,
577		.bInterfaceClass    = 0xff,
578		.bInterfaceSubClass = 0xff,
579		.bInterfaceProtocol = 0xff,
580		.driver_info        = (unsigned long)&qmi_wwan_sierra,
581	},
582
583	/* Gobi 1000 devices */
584	{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */
585	{QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */
586	{QMI_GOBI1K_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */
587	{QMI_GOBI1K_DEVICE(0x04da, 0x250d)},	/* Panasonic Gobi Modem device */
588	{QMI_GOBI1K_DEVICE(0x413c, 0x8172)},	/* Dell Gobi Modem device */
589	{QMI_GOBI1K_DEVICE(0x1410, 0xa001)},	/* Novatel Gobi Modem device */
590	{QMI_GOBI1K_DEVICE(0x0b05, 0x1776)},	/* Asus Gobi Modem device */
591	{QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)},	/* ONDA Gobi Modem device */
592	{QMI_GOBI1K_DEVICE(0x05c6, 0x9001)},	/* Generic Gobi Modem device */
593	{QMI_GOBI1K_DEVICE(0x05c6, 0x9002)},	/* Generic Gobi Modem device */
594	{QMI_GOBI1K_DEVICE(0x05c6, 0x9202)},	/* Generic Gobi Modem device */
595	{QMI_GOBI1K_DEVICE(0x05c6, 0x9203)},	/* Generic Gobi Modem device */
596	{QMI_GOBI1K_DEVICE(0x05c6, 0x9222)},	/* Generic Gobi Modem device */
597	{QMI_GOBI1K_DEVICE(0x05c6, 0x9009)},	/* Generic Gobi Modem device */
598
599	/* Gobi 2000 and 3000 devices */
600	{QMI_GOBI_DEVICE(0x413c, 0x8186)},	/* Dell Gobi 2000 Modem device (N0218, VU936) */
601	{QMI_GOBI_DEVICE(0x05c6, 0x920b)},	/* Generic Gobi 2000 Modem device */
602	{QMI_GOBI_DEVICE(0x05c6, 0x9225)},	/* Sony Gobi 2000 Modem device (N0279, VU730) */
603	{QMI_GOBI_DEVICE(0x05c6, 0x9245)},	/* Samsung Gobi 2000 Modem device (VL176) */
604	{QMI_GOBI_DEVICE(0x03f0, 0x251d)},	/* HP Gobi 2000 Modem device (VP412) */
605	{QMI_GOBI_DEVICE(0x05c6, 0x9215)},	/* Acer Gobi 2000 Modem device (VP413) */
606	{QMI_GOBI_DEVICE(0x05c6, 0x9265)},	/* Asus Gobi 2000 Modem device (VR305) */
607	{QMI_GOBI_DEVICE(0x05c6, 0x9235)},	/* Top Global Gobi 2000 Modem device (VR306) */
608	{QMI_GOBI_DEVICE(0x05c6, 0x9275)},	/* iRex Technologies Gobi 2000 Modem device (VR307) */
609	{QMI_GOBI_DEVICE(0x1199, 0x68a5)},	/* Sierra Wireless Modem */
610	{QMI_GOBI_DEVICE(0x1199, 0x68a9)},	/* Sierra Wireless Modem */
611	{QMI_GOBI_DEVICE(0x1199, 0x9001)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
612	{QMI_GOBI_DEVICE(0x1199, 0x9002)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
613	{QMI_GOBI_DEVICE(0x1199, 0x9003)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
614	{QMI_GOBI_DEVICE(0x1199, 0x9004)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
615	{QMI_GOBI_DEVICE(0x1199, 0x9005)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
616	{QMI_GOBI_DEVICE(0x1199, 0x9006)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
617	{QMI_GOBI_DEVICE(0x1199, 0x9007)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
618	{QMI_GOBI_DEVICE(0x1199, 0x9008)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
619	{QMI_GOBI_DEVICE(0x1199, 0x9009)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
620	{QMI_GOBI_DEVICE(0x1199, 0x900a)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
621	{QMI_GOBI_DEVICE(0x1199, 0x9011)},	/* Sierra Wireless Gobi 2000 Modem device (MC8305) */
622	{QMI_GOBI_DEVICE(0x16d8, 0x8002)},	/* CMDTech Gobi 2000 Modem device (VU922) */
623	{QMI_GOBI_DEVICE(0x05c6, 0x9205)},	/* Gobi 2000 Modem device */
624	{QMI_GOBI_DEVICE(0x1199, 0x9013)},	/* Sierra Wireless Gobi 3000 Modem device (MC8355) */
625	{QMI_GOBI_DEVICE(0x1199, 0x9015)},	/* Sierra Wireless Gobi 3000 Modem device */
626	{QMI_GOBI_DEVICE(0x1199, 0x9019)},	/* Sierra Wireless Gobi 3000 Modem device */
627	{QMI_GOBI_DEVICE(0x1199, 0x901b)},	/* Sierra Wireless MC7770 */
628
629	{ }					/* END */
630};
631MODULE_DEVICE_TABLE(usb, products);
632
633static struct usb_driver qmi_wwan_driver = {
634	.name		      = "qmi_wwan",
635	.id_table	      = products,
636	.probe		      =	usbnet_probe,
637	.disconnect	      = usbnet_disconnect,
638	.suspend	      = qmi_wwan_suspend,
639	.resume		      =	qmi_wwan_resume,
640	.reset_resume         = qmi_wwan_resume,
641	.supports_autosuspend = 1,
642	.disable_hub_initiated_lpm = 1,
643};
644
645static int __init qmi_wwan_init(void)
646{
647	return usb_register(&qmi_wwan_driver);
648}
649module_init(qmi_wwan_init);
650
651static void __exit qmi_wwan_exit(void)
652{
653	usb_deregister(&qmi_wwan_driver);
654}
655module_exit(qmi_wwan_exit);
656
657MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>");
658MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver");
659MODULE_LICENSE("GPL");