diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3b206786b5e7..3767a1225860 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -257,29 +257,6 @@ err: | |||
257 | return rv; | 257 | return rv; |
258 | } | 258 | } |
259 | 259 | ||
260 | /* Gobi devices uses identical class/protocol codes for all interfaces regardless | ||
261 | * of function. Some of these are CDC ACM like and have the exact same endpoints | ||
262 | * we are looking for. This leaves two possible strategies for identifying the | ||
263 | * correct interface: | ||
264 | * a) hardcoding interface number, or | ||
265 | * b) use the fact that the wwan interface is the only one lacking additional | ||
266 | * (CDC functional) descriptors | ||
267 | * | ||
268 | * Let's see if we can get away with the generic b) solution. | ||
269 | */ | ||
270 | static int qmi_wwan_bind_gobi(struct usbnet *dev, struct usb_interface *intf) | ||
271 | { | ||
272 | int rv = -EINVAL; | ||
273 | |||
274 | /* ignore any interface with additional descriptors */ | ||
275 | if (intf->cur_altsetting->extralen) | ||
276 | goto err; | ||
277 | |||
278 | rv = qmi_wwan_bind_shared(dev, intf); | ||
279 | err: | ||
280 | return rv; | ||
281 | } | ||
282 | |||
283 | static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) | 260 | static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) |
284 | { | 261 | { |
285 | struct usb_driver *subdriver = (void *)dev->data[0]; | 262 | struct usb_driver *subdriver = (void *)dev->data[0]; |
@@ -347,15 +324,15 @@ static const struct driver_info qmi_wwan_shared = { | |||
347 | .manage_power = qmi_wwan_manage_power, | 324 | .manage_power = qmi_wwan_manage_power, |
348 | }; | 325 | }; |
349 | 326 | ||
350 | static const struct driver_info qmi_wwan_gobi = { | 327 | static const struct driver_info qmi_wwan_force_int0 = { |
351 | .description = "Qualcomm Gobi wwan/QMI device", | 328 | .description = "Qualcomm WWAN/QMI device", |
352 | .flags = FLAG_WWAN, | 329 | .flags = FLAG_WWAN, |
353 | .bind = qmi_wwan_bind_gobi, | 330 | .bind = qmi_wwan_bind_shared, |
354 | .unbind = qmi_wwan_unbind_shared, | 331 | .unbind = qmi_wwan_unbind_shared, |
355 | .manage_power = qmi_wwan_manage_power, | 332 | .manage_power = qmi_wwan_manage_power, |
333 | .data = BIT(0), /* interface whitelist bitmap */ | ||
356 | }; | 334 | }; |
357 | 335 | ||
358 | /* ZTE suck at making USB descriptors */ | ||
359 | static const struct driver_info qmi_wwan_force_int1 = { | 336 | static const struct driver_info qmi_wwan_force_int1 = { |
360 | .description = "Qualcomm WWAN/QMI device", | 337 | .description = "Qualcomm WWAN/QMI device", |
361 | .flags = FLAG_WWAN, | 338 | .flags = FLAG_WWAN, |
@@ -365,6 +342,15 @@ static const struct driver_info qmi_wwan_force_int1 = { | |||
365 | .data = BIT(1), /* interface whitelist bitmap */ | 342 | .data = BIT(1), /* interface whitelist bitmap */ |
366 | }; | 343 | }; |
367 | 344 | ||
345 | static const struct driver_info qmi_wwan_force_int3 = { | ||
346 | .description = "Qualcomm WWAN/QMI device", | ||
347 | .flags = FLAG_WWAN, | ||
348 | .bind = qmi_wwan_bind_shared, | ||
349 | .unbind = qmi_wwan_unbind_shared, | ||
350 | .manage_power = qmi_wwan_manage_power, | ||
351 | .data = BIT(3), /* interface whitelist bitmap */ | ||
352 | }; | ||
353 | |||
368 | static const struct driver_info qmi_wwan_force_int4 = { | 354 | static const struct driver_info qmi_wwan_force_int4 = { |
369 | .description = "Qualcomm WWAN/QMI device", | 355 | .description = "Qualcomm WWAN/QMI device", |
370 | .flags = FLAG_WWAN, | 356 | .flags = FLAG_WWAN, |
@@ -390,16 +376,23 @@ static const struct driver_info qmi_wwan_force_int4 = { | |||
390 | static const struct driver_info qmi_wwan_sierra = { | 376 | static const struct driver_info qmi_wwan_sierra = { |
391 | .description = "Sierra Wireless wwan/QMI device", | 377 | .description = "Sierra Wireless wwan/QMI device", |
392 | .flags = FLAG_WWAN, | 378 | .flags = FLAG_WWAN, |
393 | .bind = qmi_wwan_bind_gobi, | 379 | .bind = qmi_wwan_bind_shared, |
394 | .unbind = qmi_wwan_unbind_shared, | 380 | .unbind = qmi_wwan_unbind_shared, |
395 | .manage_power = qmi_wwan_manage_power, | 381 | .manage_power = qmi_wwan_manage_power, |
396 | .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ | 382 | .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ |
397 | }; | 383 | }; |
398 | 384 | ||
399 | #define HUAWEI_VENDOR_ID 0x12D1 | 385 | #define HUAWEI_VENDOR_ID 0x12D1 |
386 | |||
387 | /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ | ||
388 | #define QMI_GOBI1K_DEVICE(vend, prod) \ | ||
389 | USB_DEVICE(vend, prod), \ | ||
390 | .driver_info = (unsigned long)&qmi_wwan_force_int3 | ||
391 | |||
392 | /* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */ | ||
400 | #define QMI_GOBI_DEVICE(vend, prod) \ | 393 | #define QMI_GOBI_DEVICE(vend, prod) \ |
401 | USB_DEVICE(vend, prod), \ | 394 | USB_DEVICE(vend, prod), \ |
402 | .driver_info = (unsigned long)&qmi_wwan_gobi | 395 | .driver_info = (unsigned long)&qmi_wwan_force_int0 |
403 | 396 | ||
404 | static const struct usb_device_id products[] = { | 397 | static const struct usb_device_id products[] = { |
405 | { /* Huawei E392, E398 and possibly others sharing both device id and more... */ | 398 | { /* Huawei E392, E398 and possibly others sharing both device id and more... */ |
@@ -510,20 +503,24 @@ static const struct usb_device_id products[] = { | |||
510 | .bInterfaceProtocol = 0xff, | 503 | .bInterfaceProtocol = 0xff, |
511 | .driver_info = (unsigned long)&qmi_wwan_sierra, | 504 | .driver_info = (unsigned long)&qmi_wwan_sierra, |
512 | }, | 505 | }, |
513 | {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 506 | |
514 | {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 507 | /* Gobi 1000 devices */ |
515 | {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | 508 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
516 | {QMI_GOBI_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ | 509 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
517 | {QMI_GOBI_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ | 510 | {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ |
518 | {QMI_GOBI_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ | 511 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ |
519 | {QMI_GOBI_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ | 512 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ |
520 | {QMI_GOBI_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ | 513 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ |
521 | {QMI_GOBI_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ | 514 | {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ |
522 | {QMI_GOBI_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ | 515 | {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ |
523 | {QMI_GOBI_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ | 516 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ |
524 | {QMI_GOBI_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ | 517 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ |
525 | {QMI_GOBI_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ | 518 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ |
526 | {QMI_GOBI_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ | 519 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ |
520 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ | ||
521 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ | ||
522 | |||
523 | /* Gobi 2000 and 3000 devices */ | ||
527 | {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ | 524 | {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ |
528 | {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ | 525 | {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ |
529 | {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ | 526 | {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ |