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 57 static 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 139 next_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 173 err: 174 return status; 175 } 176 177 /* using a counter to merge subdriver requests with our own into a combined state */ 178 static 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 } 193 err: 194 return rv; 195 } 196 197 static 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 */ 215 static 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 260 err: 261 return rv; 262 } 263 264 static 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 */ 280 static 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); 294 err: 295 return ret; 296 } 297 298 static 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); 311 err: 312 return ret; 313 } 314 315 316 static 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 323 static 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 331 static 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 340 static 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 349 static const struct driver_info qmi_wwan_force_int3 = { 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(3), /* interface whitelist bitmap */ 356 }; 357 358 static const struct driver_info qmi_wwan_force_int4 = { 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(4), /* interface whitelist bitmap */ 365 }; 366 367 /* Sierra Wireless provide equally useless interface descriptors 368 * Devices in QMI mode can be switched between two different 369 * configurations: 370 * a) USB interface #8 is QMI/wwan 371 * b) USB interfaces #8, #19 and #20 are QMI/wwan 372 * 373 * Both configurations provide a number of other interfaces (serial++), 374 * some of which have the same endpoint configuration as we expect, so 375 * a whitelist or blacklist is necessary. 376 * 377 * FIXME: The below whitelist should include BIT(20). It does not 378 * because I cannot get it to work... 379 */ 380 static const struct driver_info qmi_wwan_sierra = { 381 .description = "Sierra Wireless wwan/QMI device", 382 .flags = FLAG_WWAN, 383 .bind = qmi_wwan_bind_shared, 384 .unbind = qmi_wwan_unbind_shared, 385 .manage_power = qmi_wwan_manage_power, 386 .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ 387 }; 388 389 #define HUAWEI_VENDOR_ID 0x12D1 390 391 /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ 392 #define QMI_GOBI1K_DEVICE(vend, prod) \ 393 USB_DEVICE(vend, prod), \ 394 .driver_info = (unsigned long)&qmi_wwan_force_int3 395 396 /* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */ 397 #define QMI_GOBI_DEVICE(vend, prod) \ 398 USB_DEVICE(vend, prod), \ 399 .driver_info = (unsigned long)&qmi_wwan_force_int0 400 401 static const struct usb_device_id products[] = { 402 { /* Huawei E392, E398 and possibly others sharing both device id and more... */ 403 .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, 404 .idVendor = HUAWEI_VENDOR_ID, 405 .bInterfaceClass = USB_CLASS_VENDOR_SPEC, 406 .bInterfaceSubClass = 1, 407 .bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */ 408 .driver_info = (unsigned long)&qmi_wwan_info, 409 }, 410 { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ 411 .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, 412 .idVendor = HUAWEI_VENDOR_ID, 413 .bInterfaceClass = USB_CLASS_VENDOR_SPEC, 414 .bInterfaceSubClass = 1, 415 .bInterfaceProtocol = 56, /* NOTE: This is the *slave* interface of the CDC Union! */ 416 .driver_info = (unsigned long)&qmi_wwan_info, 417 }, 418 { /* Huawei E392, E398 and possibly others in "Windows mode" 419 * using a combined control and data interface without any CDC 420 * functional descriptors 421 */ 422 .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, 423 .idVendor = HUAWEI_VENDOR_ID, 424 .bInterfaceClass = USB_CLASS_VENDOR_SPEC, 425 .bInterfaceSubClass = 1, 426 .bInterfaceProtocol = 17, 427 .driver_info = (unsigned long)&qmi_wwan_shared, 428 }, 429 { /* Pantech UML290 */ 430 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, 431 .idVendor = 0x106c, 432 .idProduct = 0x3718, 433 .bInterfaceClass = 0xff, 434 .bInterfaceSubClass = 0xf0, 435 .bInterfaceProtocol = 0xff, 436 .driver_info = (unsigned long)&qmi_wwan_shared, 437 }, 438 { /* ZTE MF820D */ 439 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, 440 .idVendor = 0x19d2, 441 .idProduct = 0x0167, 442 .bInterfaceClass = 0xff, 443 .bInterfaceSubClass = 0xff, 444 .bInterfaceProtocol = 0xff, 445 .driver_info = (unsigned long)&qmi_wwan_force_int4, 446 }, 447 { /* ZTE (Vodafone) K3520-Z */ 448 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, 449 .idVendor = 0x19d2, 450 .idProduct = 0x0055, 451 .bInterfaceClass = 0xff, 452 .bInterfaceSubClass = 0xff, 453 .bInterfaceProtocol = 0xff, 454 .driver_info = (unsigned long)&qmi_wwan_force_int1, 455 }, 456 { /* ZTE (Vodafone) K3565-Z */ 457 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, 458 .idVendor = 0x19d2, 459 .idProduct = 0x0063, 460 .bInterfaceClass = 0xff, 461 .bInterfaceSubClass = 0xff, 462 .bInterfaceProtocol = 0xff, 463 .driver_info = (unsigned long)&qmi_wwan_force_int4, 464 }, 465 { /* ZTE (Vodafone) K3570-Z */ 466 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, 467 .idVendor = 0x19d2, 468 .idProduct = 0x1008, 469 .bInterfaceClass = 0xff, 470 .bInterfaceSubClass = 0xff, 471 .bInterfaceProtocol = 0xff, 472 .driver_info = (unsigned long)&qmi_wwan_force_int4, 473 }, 474 { /* ZTE (Vodafone) K3571-Z */ 475 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, 476 .idVendor = 0x19d2, 477 .idProduct = 0x1010, 478 .bInterfaceClass = 0xff, 479 .bInterfaceSubClass = 0xff, 480 .bInterfaceProtocol = 0xff, 481 .driver_info = (unsigned long)&qmi_wwan_force_int4, 482 }, 483 { /* ZTE (Vodafone) K3765-Z */ 484 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, 485 .idVendor = 0x19d2, 486 .idProduct = 0x2002, 487 .bInterfaceClass = 0xff, 488 .bInterfaceSubClass = 0xff, 489 .bInterfaceProtocol = 0xff, 490 .driver_info = (unsigned long)&qmi_wwan_force_int4, 491 }, 492 { /* ZTE (Vodafone) K4505-Z */ 493 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, 494 .idVendor = 0x19d2, 495 .idProduct = 0x0104, 496 .bInterfaceClass = 0xff, 497 .bInterfaceSubClass = 0xff, 498 .bInterfaceProtocol = 0xff, 499 .driver_info = (unsigned long)&qmi_wwan_force_int4, 500 }, 501 { /* Sierra Wireless MC77xx in QMI mode */ 502 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, 503 .idVendor = 0x1199, 504 .idProduct = 0x68a2, 505 .bInterfaceClass = 0xff, 506 .bInterfaceSubClass = 0xff, 507 .bInterfaceProtocol = 0xff, 508 .driver_info = (unsigned long)&qmi_wwan_sierra, 509 }, 510 511 /* Gobi 1000 devices */ 512 {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ 513 {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ 514 {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ 515 {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ 516 {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ 517 {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ 518 {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ 519 {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ 520 {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ 521 {QMI_GOBI1K_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ 522 {QMI_GOBI1K_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ 523 {QMI_GOBI1K_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ 524 {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ 525 {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ 526 527 /* Gobi 2000 and 3000 devices */ 528 {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ 529 {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ 530 {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ 531 {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ 532 {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ 533 {QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ 534 {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ 535 {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ 536 {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ 537 {QMI_GOBI_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 538 {QMI_GOBI_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 539 {QMI_GOBI_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 540 {QMI_GOBI_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 541 {QMI_GOBI_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 542 {QMI_GOBI_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 543 {QMI_GOBI_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 544 {QMI_GOBI_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 545 {QMI_GOBI_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 546 {QMI_GOBI_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 547 {QMI_GOBI_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ 548 {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ 549 {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ 550 {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ 551 {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ 552 {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ 553 { } /* END */ 554 }; 555 MODULE_DEVICE_TABLE(usb, products); 556 557 static struct usb_driver qmi_wwan_driver = { 558 .name = "qmi_wwan", 559 .id_table = products, 560 .probe = usbnet_probe, 561 .disconnect = usbnet_disconnect, 562 .suspend = qmi_wwan_suspend, 563 .resume = qmi_wwan_resume, 564 .reset_resume = qmi_wwan_resume, 565 .supports_autosuspend = 1, 566 .disable_hub_initiated_lpm = 1, 567 }; 568 569 static int __init qmi_wwan_init(void) 570 { 571 return usb_register(&qmi_wwan_driver); 572 } 573 module_init(qmi_wwan_init); 574 575 static void __exit qmi_wwan_exit(void) 576 { 577 usb_deregister(&qmi_wwan_driver); 578 } 579 module_exit(qmi_wwan_exit); 580 581 MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>"); 582 MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver"); 583 MODULE_LICENSE("GPL"); 584