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