aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/cdc_ether.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/cdc_ether.c')
-rw-r--r--drivers/net/usb/cdc_ether.c79
1 files changed, 48 insertions, 31 deletions
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 21e1ba160008..21e183a83b99 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -37,23 +37,23 @@
37 37
38static int is_rndis(struct usb_interface_descriptor *desc) 38static int is_rndis(struct usb_interface_descriptor *desc)
39{ 39{
40 return desc->bInterfaceClass == USB_CLASS_COMM 40 return (desc->bInterfaceClass == USB_CLASS_COMM &&
41 && desc->bInterfaceSubClass == 2 41 desc->bInterfaceSubClass == 2 &&
42 && desc->bInterfaceProtocol == 0xff; 42 desc->bInterfaceProtocol == 0xff);
43} 43}
44 44
45static int is_activesync(struct usb_interface_descriptor *desc) 45static int is_activesync(struct usb_interface_descriptor *desc)
46{ 46{
47 return desc->bInterfaceClass == USB_CLASS_MISC 47 return (desc->bInterfaceClass == USB_CLASS_MISC &&
48 && desc->bInterfaceSubClass == 1 48 desc->bInterfaceSubClass == 1 &&
49 && desc->bInterfaceProtocol == 1; 49 desc->bInterfaceProtocol == 1);
50} 50}
51 51
52static int is_wireless_rndis(struct usb_interface_descriptor *desc) 52static int is_wireless_rndis(struct usb_interface_descriptor *desc)
53{ 53{
54 return desc->bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER 54 return (desc->bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER &&
55 && desc->bInterfaceSubClass == 1 55 desc->bInterfaceSubClass == 1 &&
56 && desc->bInterfaceProtocol == 3; 56 desc->bInterfaceProtocol == 3);
57} 57}
58 58
59#else 59#else
@@ -116,9 +116,9 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
116 /* this assumes that if there's a non-RNDIS vendor variant 116 /* this assumes that if there's a non-RNDIS vendor variant
117 * of cdc-acm, it'll fail RNDIS requests cleanly. 117 * of cdc-acm, it'll fail RNDIS requests cleanly.
118 */ 118 */
119 rndis = is_rndis(&intf->cur_altsetting->desc) 119 rndis = (is_rndis(&intf->cur_altsetting->desc) ||
120 || is_activesync(&intf->cur_altsetting->desc) 120 is_activesync(&intf->cur_altsetting->desc) ||
121 || is_wireless_rndis(&intf->cur_altsetting->desc); 121 is_wireless_rndis(&intf->cur_altsetting->desc));
122 122
123 memset(info, 0, sizeof *info); 123 memset(info, 0, sizeof *info);
124 info->control = intf; 124 info->control = intf;
@@ -279,10 +279,10 @@ next_desc:
279 279
280 dev->status = &info->control->cur_altsetting->endpoint [0]; 280 dev->status = &info->control->cur_altsetting->endpoint [0];
281 desc = &dev->status->desc; 281 desc = &dev->status->desc;
282 if (!usb_endpoint_is_int_in(desc) 282 if (!usb_endpoint_is_int_in(desc) ||
283 || (le16_to_cpu(desc->wMaxPacketSize) 283 (le16_to_cpu(desc->wMaxPacketSize)
284 < sizeof(struct usb_cdc_notification)) 284 < sizeof(struct usb_cdc_notification)) ||
285 || !desc->bInterval) { 285 !desc->bInterval) {
286 dev_dbg(&intf->dev, "bad notification endpoint\n"); 286 dev_dbg(&intf->dev, "bad notification endpoint\n");
287 dev->status = NULL; 287 dev->status = NULL;
288 } 288 }
@@ -411,13 +411,28 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
411 return 0; 411 return 0;
412} 412}
413 413
414static int cdc_manage_power(struct usbnet *dev, int on)
415{
416 dev->intf->needs_remote_wakeup = on;
417 return 0;
418}
419
414static const struct driver_info cdc_info = { 420static const struct driver_info cdc_info = {
415 .description = "CDC Ethernet Device", 421 .description = "CDC Ethernet Device",
416 .flags = FLAG_ETHER, 422 .flags = FLAG_ETHER | FLAG_LINK_INTR,
417 // .check_connect = cdc_check_connect, 423 // .check_connect = cdc_check_connect,
418 .bind = cdc_bind, 424 .bind = cdc_bind,
419 .unbind = usbnet_cdc_unbind, 425 .unbind = usbnet_cdc_unbind,
420 .status = cdc_status, 426 .status = cdc_status,
427 .manage_power = cdc_manage_power,
428};
429
430static const struct driver_info mbm_info = {
431 .description = "Mobile Broadband Network Device",
432 .flags = FLAG_WWAN,
433 .bind = cdc_bind,
434 .unbind = usbnet_cdc_unbind,
435 .status = cdc_status,
421}; 436};
422 437
423/*-------------------------------------------------------------------------*/ 438/*-------------------------------------------------------------------------*/
@@ -532,72 +547,72 @@ static const struct usb_device_id products [] = {
532 /* Ericsson F3507g */ 547 /* Ericsson F3507g */
533 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM, 548 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM,
534 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 549 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
535 .driver_info = (unsigned long) &cdc_info, 550 .driver_info = (unsigned long) &mbm_info,
536}, { 551}, {
537 /* Ericsson F3507g ver. 2 */ 552 /* Ericsson F3507g ver. 2 */
538 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1902, USB_CLASS_COMM, 553 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1902, USB_CLASS_COMM,
539 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 554 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
540 .driver_info = (unsigned long) &cdc_info, 555 .driver_info = (unsigned long) &mbm_info,
541}, { 556}, {
542 /* Ericsson F3607gw */ 557 /* Ericsson F3607gw */
543 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1904, USB_CLASS_COMM, 558 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1904, USB_CLASS_COMM,
544 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 559 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
545 .driver_info = (unsigned long) &cdc_info, 560 .driver_info = (unsigned long) &mbm_info,
546}, { 561}, {
547 /* Ericsson F3607gw ver 2 */ 562 /* Ericsson F3607gw ver 2 */
548 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM, 563 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM,
549 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 564 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
550 .driver_info = (unsigned long) &cdc_info, 565 .driver_info = (unsigned long) &mbm_info,
551}, { 566}, {
552 /* Ericsson F3607gw ver 3 */ 567 /* Ericsson F3607gw ver 3 */
553 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM, 568 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM,
554 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 569 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
555 .driver_info = (unsigned long) &cdc_info, 570 .driver_info = (unsigned long) &mbm_info,
556}, { 571}, {
557 /* Ericsson F3307 */ 572 /* Ericsson F3307 */
558 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM, 573 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM,
559 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 574 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
560 .driver_info = (unsigned long) &cdc_info, 575 .driver_info = (unsigned long) &mbm_info,
561}, { 576}, {
562 /* Ericsson F3307 ver 2 */ 577 /* Ericsson F3307 ver 2 */
563 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM, 578 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM,
564 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 579 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
565 .driver_info = (unsigned long) &cdc_info, 580 .driver_info = (unsigned long) &mbm_info,
566}, { 581}, {
567 /* Ericsson C3607w */ 582 /* Ericsson C3607w */
568 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM, 583 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM,
569 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 584 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
570 .driver_info = (unsigned long) &cdc_info, 585 .driver_info = (unsigned long) &mbm_info,
571}, { 586}, {
572 /* Toshiba F3507g */ 587 /* Toshiba F3507g */
573 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM, 588 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,
574 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 589 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
575 .driver_info = (unsigned long) &cdc_info, 590 .driver_info = (unsigned long) &mbm_info,
576}, { 591}, {
577 /* Toshiba F3607gw */ 592 /* Toshiba F3607gw */
578 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM, 593 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM,
579 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 594 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
580 .driver_info = (unsigned long) &cdc_info, 595 .driver_info = (unsigned long) &mbm_info,
581}, { 596}, {
582 /* Toshiba F3607gw ver 2 */ 597 /* Toshiba F3607gw ver 2 */
583 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM, 598 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM,
584 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 599 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
585 .driver_info = (unsigned long) &cdc_info, 600 .driver_info = (unsigned long) &mbm_info,
586}, { 601}, {
587 /* Dell F3507g */ 602 /* Dell F3507g */
588 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM, 603 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM,
589 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 604 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
590 .driver_info = (unsigned long) &cdc_info, 605 .driver_info = (unsigned long) &mbm_info,
591}, { 606}, {
592 /* Dell F3607gw */ 607 /* Dell F3607gw */
593 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM, 608 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM,
594 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 609 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
595 .driver_info = (unsigned long) &cdc_info, 610 .driver_info = (unsigned long) &mbm_info,
596}, { 611}, {
597 /* Dell F3607gw ver 2 */ 612 /* Dell F3607gw ver 2 */
598 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM, 613 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM,
599 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 614 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
600 .driver_info = (unsigned long) &cdc_info, 615 .driver_info = (unsigned long) &mbm_info,
601}, 616},
602 { }, // END 617 { }, // END
603}; 618};
@@ -610,6 +625,8 @@ static struct usb_driver cdc_driver = {
610 .disconnect = usbnet_disconnect, 625 .disconnect = usbnet_disconnect,
611 .suspend = usbnet_suspend, 626 .suspend = usbnet_suspend,
612 .resume = usbnet_resume, 627 .resume = usbnet_resume,
628 .reset_resume = usbnet_resume,
629 .supports_autosuspend = 1,
613}; 630};
614 631
615 632