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.c105
1 files changed, 63 insertions, 42 deletions
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 21e1ba160008..3547cf13d219 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 }
@@ -339,10 +339,10 @@ EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
339 339
340static void dumpspeed(struct usbnet *dev, __le32 *speeds) 340static void dumpspeed(struct usbnet *dev, __le32 *speeds)
341{ 341{
342 if (netif_msg_timer(dev)) 342 netif_info(dev, timer, dev->net,
343 devinfo(dev, "link speeds: %u kbps up, %u kbps down", 343 "link speeds: %u kbps up, %u kbps down\n",
344 __le32_to_cpu(speeds[0]) / 1000, 344 __le32_to_cpu(speeds[0]) / 1000,
345 __le32_to_cpu(speeds[1]) / 1000); 345 __le32_to_cpu(speeds[1]) / 1000);
346} 346}
347 347
348static void cdc_status(struct usbnet *dev, struct urb *urb) 348static void cdc_status(struct usbnet *dev, struct urb *urb)
@@ -361,18 +361,16 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
361 event = urb->transfer_buffer; 361 event = urb->transfer_buffer;
362 switch (event->bNotificationType) { 362 switch (event->bNotificationType) {
363 case USB_CDC_NOTIFY_NETWORK_CONNECTION: 363 case USB_CDC_NOTIFY_NETWORK_CONNECTION:
364 if (netif_msg_timer(dev)) 364 netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
365 devdbg(dev, "CDC: carrier %s", 365 event->wValue ? "on" : "off");
366 event->wValue ? "on" : "off");
367 if (event->wValue) 366 if (event->wValue)
368 netif_carrier_on(dev->net); 367 netif_carrier_on(dev->net);
369 else 368 else
370 netif_carrier_off(dev->net); 369 netif_carrier_off(dev->net);
371 break; 370 break;
372 case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */ 371 case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
373 if (netif_msg_timer(dev)) 372 netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n",
374 devdbg(dev, "CDC: speed change (len %d)", 373 urb->actual_length);
375 urb->actual_length);
376 if (urb->actual_length != (sizeof *event + 8)) 374 if (urb->actual_length != (sizeof *event + 8))
377 set_bit(EVENT_STS_SPLIT, &dev->flags); 375 set_bit(EVENT_STS_SPLIT, &dev->flags);
378 else 376 else
@@ -382,8 +380,8 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
382 * but there are no standard formats for the response data. 380 * but there are no standard formats for the response data.
383 */ 381 */
384 default: 382 default:
385 deverr(dev, "CDC: unexpected notification %02x!", 383 netdev_err(dev->net, "CDC: unexpected notification %02x!\n",
386 event->bNotificationType); 384 event->bNotificationType);
387 break; 385 break;
388 } 386 }
389} 387}
@@ -411,6 +409,12 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
411 return 0; 409 return 0;
412} 410}
413 411
412static int cdc_manage_power(struct usbnet *dev, int on)
413{
414 dev->intf->needs_remote_wakeup = on;
415 return 0;
416}
417
414static const struct driver_info cdc_info = { 418static const struct driver_info cdc_info = {
415 .description = "CDC Ethernet Device", 419 .description = "CDC Ethernet Device",
416 .flags = FLAG_ETHER, 420 .flags = FLAG_ETHER,
@@ -418,6 +422,16 @@ static const struct driver_info cdc_info = {
418 .bind = cdc_bind, 422 .bind = cdc_bind,
419 .unbind = usbnet_cdc_unbind, 423 .unbind = usbnet_cdc_unbind,
420 .status = cdc_status, 424 .status = cdc_status,
425 .manage_power = cdc_manage_power,
426};
427
428static const struct driver_info mbm_info = {
429 .description = "Mobile Broadband Network Device",
430 .flags = FLAG_WWAN,
431 .bind = cdc_bind,
432 .unbind = usbnet_cdc_unbind,
433 .status = cdc_status,
434 .manage_power = cdc_manage_power,
421}; 435};
422 436
423/*-------------------------------------------------------------------------*/ 437/*-------------------------------------------------------------------------*/
@@ -532,72 +546,77 @@ static const struct usb_device_id products [] = {
532 /* Ericsson F3507g */ 546 /* Ericsson F3507g */
533 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM, 547 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM,
534 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 548 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
535 .driver_info = (unsigned long) &cdc_info, 549 .driver_info = (unsigned long) &mbm_info,
536}, { 550}, {
537 /* Ericsson F3507g ver. 2 */ 551 /* Ericsson F3507g ver. 2 */
538 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1902, USB_CLASS_COMM, 552 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1902, USB_CLASS_COMM,
539 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 553 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
540 .driver_info = (unsigned long) &cdc_info, 554 .driver_info = (unsigned long) &mbm_info,
541}, { 555}, {
542 /* Ericsson F3607gw */ 556 /* Ericsson F3607gw */
543 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1904, USB_CLASS_COMM, 557 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1904, USB_CLASS_COMM,
544 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 558 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
545 .driver_info = (unsigned long) &cdc_info, 559 .driver_info = (unsigned long) &mbm_info,
546}, { 560}, {
547 /* Ericsson F3607gw ver 2 */ 561 /* Ericsson F3607gw ver 2 */
548 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM, 562 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM,
549 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 563 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
550 .driver_info = (unsigned long) &cdc_info, 564 .driver_info = (unsigned long) &mbm_info,
551}, { 565}, {
552 /* Ericsson F3607gw ver 3 */ 566 /* Ericsson F3607gw ver 3 */
553 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM, 567 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM,
554 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 568 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
555 .driver_info = (unsigned long) &cdc_info, 569 .driver_info = (unsigned long) &mbm_info,
556}, { 570}, {
557 /* Ericsson F3307 */ 571 /* Ericsson F3307 */
558 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM, 572 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM,
559 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 573 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
560 .driver_info = (unsigned long) &cdc_info, 574 .driver_info = (unsigned long) &mbm_info,
561}, { 575}, {
562 /* Ericsson F3307 ver 2 */ 576 /* Ericsson F3307 ver 2 */
563 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM, 577 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM,
564 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 578 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
565 .driver_info = (unsigned long) &cdc_info, 579 .driver_info = (unsigned long) &mbm_info,
566}, { 580}, {
567 /* Ericsson C3607w */ 581 /* Ericsson C3607w */
568 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM, 582 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM,
569 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 583 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
570 .driver_info = (unsigned long) &cdc_info, 584 .driver_info = (unsigned long) &mbm_info,
585}, {
586 /* Ericsson C3607w ver 2 */
587 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190b, USB_CLASS_COMM,
588 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
589 .driver_info = (unsigned long) &mbm_info,
571}, { 590}, {
572 /* Toshiba F3507g */ 591 /* Toshiba F3507g */
573 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM, 592 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,
574 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 593 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
575 .driver_info = (unsigned long) &cdc_info, 594 .driver_info = (unsigned long) &mbm_info,
576}, { 595}, {
577 /* Toshiba F3607gw */ 596 /* Toshiba F3607gw */
578 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM, 597 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM,
579 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 598 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
580 .driver_info = (unsigned long) &cdc_info, 599 .driver_info = (unsigned long) &mbm_info,
581}, { 600}, {
582 /* Toshiba F3607gw ver 2 */ 601 /* Toshiba F3607gw ver 2 */
583 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM, 602 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM,
584 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 603 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
585 .driver_info = (unsigned long) &cdc_info, 604 .driver_info = (unsigned long) &mbm_info,
586}, { 605}, {
587 /* Dell F3507g */ 606 /* Dell F3507g */
588 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM, 607 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM,
589 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 608 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
590 .driver_info = (unsigned long) &cdc_info, 609 .driver_info = (unsigned long) &mbm_info,
591}, { 610}, {
592 /* Dell F3607gw */ 611 /* Dell F3607gw */
593 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM, 612 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM,
594 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 613 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
595 .driver_info = (unsigned long) &cdc_info, 614 .driver_info = (unsigned long) &mbm_info,
596}, { 615}, {
597 /* Dell F3607gw ver 2 */ 616 /* Dell F3607gw ver 2 */
598 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM, 617 USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM,
599 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 618 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
600 .driver_info = (unsigned long) &cdc_info, 619 .driver_info = (unsigned long) &mbm_info,
601}, 620},
602 { }, // END 621 { }, // END
603}; 622};
@@ -610,6 +629,8 @@ static struct usb_driver cdc_driver = {
610 .disconnect = usbnet_disconnect, 629 .disconnect = usbnet_disconnect,
611 .suspend = usbnet_suspend, 630 .suspend = usbnet_suspend,
612 .resume = usbnet_resume, 631 .resume = usbnet_resume,
632 .reset_resume = usbnet_resume,
633 .supports_autosuspend = 1,
613}; 634};
614 635
615 636