diff options
-rw-r--r-- | drivers/usb/gadget/ether.c | 142 |
1 files changed, 103 insertions, 39 deletions
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index ca8e0ebc79e8..72e2b65293c8 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -72,9 +72,18 @@ | |||
72 | * | 72 | * |
73 | * There's some hardware that can't talk CDC. We make that hardware | 73 | * There's some hardware that can't talk CDC. We make that hardware |
74 | * implement a "minimalist" vendor-agnostic CDC core: same framing, but | 74 | * implement a "minimalist" vendor-agnostic CDC core: same framing, but |
75 | * link-level setup only requires activating the configuration. | 75 | * link-level setup only requires activating the configuration. Only the |
76 | * Linux supports it, but other host operating systems may not. | 76 | * endpoint descriptors, and product/vendor IDs, are relevant; no control |
77 | * (This is a subset of CDC Ethernet.) | 77 | * operations are available. Linux supports it, but other host operating |
78 | * systems may not. (This is a subset of CDC Ethernet.) | ||
79 | * | ||
80 | * It turns out that if you add a few descriptors to that "CDC Subset", | ||
81 | * (Windows) host side drivers from MCCI can treat it as one submode of | ||
82 | * a proprietary scheme called "SAFE" ... without needing to know about | ||
83 | * specific product/vendor IDs. So we do that, making it easier to use | ||
84 | * those MS-Windows drivers. Those added descriptors make it resemble a | ||
85 | * CDC MDLM device, but they don't change device behavior at all. (See | ||
86 | * MCCI Engineering report 950198 "SAFE Networking Functions".) | ||
78 | * | 87 | * |
79 | * A third option is also in use. Rather than CDC Ethernet, or something | 88 | * A third option is also in use. Rather than CDC Ethernet, or something |
80 | * simpler, Microsoft pushes their own approach: RNDIS. The published | 89 | * simpler, Microsoft pushes their own approach: RNDIS. The published |
@@ -254,6 +263,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
254 | #define DEV_CONFIG_CDC | 263 | #define DEV_CONFIG_CDC |
255 | #endif | 264 | #endif |
256 | 265 | ||
266 | #ifdef CONFIG_USB_GADGET_S3C2410 | ||
267 | #define DEV_CONFIG_CDC | ||
268 | #endif | ||
269 | |||
257 | #ifdef CONFIG_USB_GADGET_AT91 | 270 | #ifdef CONFIG_USB_GADGET_AT91 |
258 | #define DEV_CONFIG_CDC | 271 | #define DEV_CONFIG_CDC |
259 | #endif | 272 | #endif |
@@ -283,9 +296,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
283 | #define DEV_CONFIG_SUBSET | 296 | #define DEV_CONFIG_SUBSET |
284 | #endif | 297 | #endif |
285 | 298 | ||
286 | #ifdef CONFIG_USB_GADGET_S3C2410 | ||
287 | #define DEV_CONFIG_CDC | ||
288 | #endif | ||
289 | 299 | ||
290 | /*-------------------------------------------------------------------------*/ | 300 | /*-------------------------------------------------------------------------*/ |
291 | 301 | ||
@@ -487,8 +497,17 @@ rndis_config = { | |||
487 | * endpoint. Both have a "data" interface and two bulk endpoints. | 497 | * endpoint. Both have a "data" interface and two bulk endpoints. |
488 | * There are also differences in how control requests are handled. | 498 | * There are also differences in how control requests are handled. |
489 | * | 499 | * |
490 | * RNDIS shares a lot with CDC-Ethernet, since it's a variant of | 500 | * RNDIS shares a lot with CDC-Ethernet, since it's a variant of the |
491 | * the CDC-ACM (modem) spec. | 501 | * CDC-ACM (modem) spec. Unfortunately MSFT's RNDIS driver is buggy; it |
502 | * may hang or oops. Since bugfixes (or accurate specs, letting Linux | ||
503 | * work around those bugs) are unlikely to ever come from MSFT, you may | ||
504 | * wish to avoid using RNDIS. | ||
505 | * | ||
506 | * MCCI offers an alternative to RNDIS if you need to connect to Windows | ||
507 | * but have hardware that can't support CDC Ethernet. We add descriptors | ||
508 | * to present the CDC Subset as a (nonconformant) CDC MDLM variant called | ||
509 | * "SAFE". That borrows from both CDC Ethernet and CDC MDLM. You can | ||
510 | * get those drivers from MCCI, or bundled with various products. | ||
492 | */ | 511 | */ |
493 | 512 | ||
494 | #ifdef DEV_CONFIG_CDC | 513 | #ifdef DEV_CONFIG_CDC |
@@ -522,8 +541,6 @@ rndis_control_intf = { | |||
522 | }; | 541 | }; |
523 | #endif | 542 | #endif |
524 | 543 | ||
525 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | ||
526 | |||
527 | static const struct usb_cdc_header_desc header_desc = { | 544 | static const struct usb_cdc_header_desc header_desc = { |
528 | .bLength = sizeof header_desc, | 545 | .bLength = sizeof header_desc, |
529 | .bDescriptorType = USB_DT_CS_INTERFACE, | 546 | .bDescriptorType = USB_DT_CS_INTERFACE, |
@@ -532,6 +549,8 @@ static const struct usb_cdc_header_desc header_desc = { | |||
532 | .bcdCDC = __constant_cpu_to_le16 (0x0110), | 549 | .bcdCDC = __constant_cpu_to_le16 (0x0110), |
533 | }; | 550 | }; |
534 | 551 | ||
552 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | ||
553 | |||
535 | static const struct usb_cdc_union_desc union_desc = { | 554 | static const struct usb_cdc_union_desc union_desc = { |
536 | .bLength = sizeof union_desc, | 555 | .bLength = sizeof union_desc, |
537 | .bDescriptorType = USB_DT_CS_INTERFACE, | 556 | .bDescriptorType = USB_DT_CS_INTERFACE, |
@@ -564,7 +583,40 @@ static const struct usb_cdc_acm_descriptor acm_descriptor = { | |||
564 | 583 | ||
565 | #endif | 584 | #endif |
566 | 585 | ||
567 | #ifdef DEV_CONFIG_CDC | 586 | #ifndef DEV_CONFIG_CDC |
587 | |||
588 | /* "SAFE" loosely follows CDC WMC MDLM, violating the spec in various | ||
589 | * ways: data endpoints live in the control interface, there's no data | ||
590 | * interface, and it's not used to talk to a cell phone radio. | ||
591 | */ | ||
592 | |||
593 | static const struct usb_cdc_mdlm_desc mdlm_desc = { | ||
594 | .bLength = sizeof mdlm_desc, | ||
595 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
596 | .bDescriptorSubType = USB_CDC_MDLM_TYPE, | ||
597 | |||
598 | .bcdVersion = __constant_cpu_to_le16(0x0100), | ||
599 | .bGUID = { | ||
600 | 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, | ||
601 | 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, | ||
602 | }, | ||
603 | }; | ||
604 | |||
605 | /* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we | ||
606 | * can't really use its struct. All we do here is say that we're using | ||
607 | * the submode of "SAFE" which directly matches the CDC Subset. | ||
608 | */ | ||
609 | static const u8 mdlm_detail_desc[] = { | ||
610 | 6, | ||
611 | USB_DT_CS_INTERFACE, | ||
612 | USB_CDC_MDLM_DETAIL_TYPE, | ||
613 | |||
614 | 0, /* "SAFE" */ | ||
615 | 0, /* network control capabilities (none) */ | ||
616 | 0, /* network data capabilities ("raw" encapsulation) */ | ||
617 | }; | ||
618 | |||
619 | #endif | ||
568 | 620 | ||
569 | static const struct usb_cdc_ether_desc ether_desc = { | 621 | static const struct usb_cdc_ether_desc ether_desc = { |
570 | .bLength = sizeof ether_desc, | 622 | .bLength = sizeof ether_desc, |
@@ -579,7 +631,6 @@ static const struct usb_cdc_ether_desc ether_desc = { | |||
579 | .bNumberPowerFilters = 0, | 631 | .bNumberPowerFilters = 0, |
580 | }; | 632 | }; |
581 | 633 | ||
582 | #endif | ||
583 | 634 | ||
584 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | 635 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) |
585 | 636 | ||
@@ -672,6 +723,9 @@ rndis_data_intf = { | |||
672 | /* | 723 | /* |
673 | * "Simple" CDC-subset option is a simple vendor-neutral model that most | 724 | * "Simple" CDC-subset option is a simple vendor-neutral model that most |
674 | * full speed controllers can handle: one interface, two bulk endpoints. | 725 | * full speed controllers can handle: one interface, two bulk endpoints. |
726 | * | ||
727 | * To assist host side drivers, we fancy it up a bit, and add descriptors | ||
728 | * so some host side drivers will understand it as a "SAFE" variant. | ||
675 | */ | 729 | */ |
676 | 730 | ||
677 | static const struct usb_interface_descriptor | 731 | static const struct usb_interface_descriptor |
@@ -682,8 +736,8 @@ subset_data_intf = { | |||
682 | .bInterfaceNumber = 0, | 736 | .bInterfaceNumber = 0, |
683 | .bAlternateSetting = 0, | 737 | .bAlternateSetting = 0, |
684 | .bNumEndpoints = 2, | 738 | .bNumEndpoints = 2, |
685 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | 739 | .bInterfaceClass = USB_CLASS_COMM, |
686 | .bInterfaceSubClass = 0, | 740 | .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, |
687 | .bInterfaceProtocol = 0, | 741 | .bInterfaceProtocol = 0, |
688 | .iInterface = STRING_DATA, | 742 | .iInterface = STRING_DATA, |
689 | }; | 743 | }; |
@@ -731,10 +785,15 @@ static const struct usb_descriptor_header *fs_eth_function [11] = { | |||
731 | static inline void __init fs_subset_descriptors(void) | 785 | static inline void __init fs_subset_descriptors(void) |
732 | { | 786 | { |
733 | #ifdef DEV_CONFIG_SUBSET | 787 | #ifdef DEV_CONFIG_SUBSET |
788 | /* behavior is "CDC Subset"; extra descriptors say "SAFE" */ | ||
734 | fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; | 789 | fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; |
735 | fs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc; | 790 | fs_eth_function[2] = (struct usb_descriptor_header *) &header_desc; |
736 | fs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc; | 791 | fs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc; |
737 | fs_eth_function[4] = NULL; | 792 | fs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc; |
793 | fs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc; | ||
794 | fs_eth_function[6] = (struct usb_descriptor_header *) &fs_source_desc; | ||
795 | fs_eth_function[7] = (struct usb_descriptor_header *) &fs_sink_desc; | ||
796 | fs_eth_function[8] = NULL; | ||
738 | #else | 797 | #else |
739 | fs_eth_function[1] = NULL; | 798 | fs_eth_function[1] = NULL; |
740 | #endif | 799 | #endif |
@@ -828,10 +887,15 @@ static const struct usb_descriptor_header *hs_eth_function [11] = { | |||
828 | static inline void __init hs_subset_descriptors(void) | 887 | static inline void __init hs_subset_descriptors(void) |
829 | { | 888 | { |
830 | #ifdef DEV_CONFIG_SUBSET | 889 | #ifdef DEV_CONFIG_SUBSET |
890 | /* behavior is "CDC Subset"; extra descriptors say "SAFE" */ | ||
831 | hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; | 891 | hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; |
832 | hs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc; | 892 | hs_eth_function[2] = (struct usb_descriptor_header *) &header_desc; |
833 | hs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc; | 893 | hs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc; |
834 | hs_eth_function[4] = NULL; | 894 | hs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc; |
895 | hs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc; | ||
896 | hs_eth_function[6] = (struct usb_descriptor_header *) &hs_source_desc; | ||
897 | hs_eth_function[7] = (struct usb_descriptor_header *) &hs_sink_desc; | ||
898 | hs_eth_function[8] = NULL; | ||
835 | #else | 899 | #else |
836 | hs_eth_function[1] = NULL; | 900 | hs_eth_function[1] = NULL; |
837 | #endif | 901 | #endif |
@@ -878,10 +942,8 @@ static char manufacturer [50]; | |||
878 | static char product_desc [40] = DRIVER_DESC; | 942 | static char product_desc [40] = DRIVER_DESC; |
879 | static char serial_number [20]; | 943 | static char serial_number [20]; |
880 | 944 | ||
881 | #ifdef DEV_CONFIG_CDC | ||
882 | /* address that the host will use ... usually assigned at random */ | 945 | /* address that the host will use ... usually assigned at random */ |
883 | static char ethaddr [2 * ETH_ALEN + 1]; | 946 | static char ethaddr [2 * ETH_ALEN + 1]; |
884 | #endif | ||
885 | 947 | ||
886 | /* static strings, in UTF-8 */ | 948 | /* static strings, in UTF-8 */ |
887 | static struct usb_string strings [] = { | 949 | static struct usb_string strings [] = { |
@@ -889,9 +951,9 @@ static struct usb_string strings [] = { | |||
889 | { STRING_PRODUCT, product_desc, }, | 951 | { STRING_PRODUCT, product_desc, }, |
890 | { STRING_SERIALNUMBER, serial_number, }, | 952 | { STRING_SERIALNUMBER, serial_number, }, |
891 | { STRING_DATA, "Ethernet Data", }, | 953 | { STRING_DATA, "Ethernet Data", }, |
954 | { STRING_ETHADDR, ethaddr, }, | ||
892 | #ifdef DEV_CONFIG_CDC | 955 | #ifdef DEV_CONFIG_CDC |
893 | { STRING_CDC, "CDC Ethernet", }, | 956 | { STRING_CDC, "CDC Ethernet", }, |
894 | { STRING_ETHADDR, ethaddr, }, | ||
895 | { STRING_CONTROL, "CDC Communications Control", }, | 957 | { STRING_CONTROL, "CDC Communications Control", }, |
896 | #endif | 958 | #endif |
897 | #ifdef DEV_CONFIG_SUBSET | 959 | #ifdef DEV_CONFIG_SUBSET |
@@ -986,10 +1048,10 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags) | |||
986 | } | 1048 | } |
987 | #endif | 1049 | #endif |
988 | 1050 | ||
989 | dev->in = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc); | 1051 | dev->in = ep_desc(gadget, &hs_source_desc, &fs_source_desc); |
990 | dev->in_ep->driver_data = dev; | 1052 | dev->in_ep->driver_data = dev; |
991 | 1053 | ||
992 | dev->out = ep_desc (dev->gadget, &hs_sink_desc, &fs_sink_desc); | 1054 | dev->out = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); |
993 | dev->out_ep->driver_data = dev; | 1055 | dev->out_ep->driver_data = dev; |
994 | 1056 | ||
995 | /* With CDC, the host isn't allowed to use these two data | 1057 | /* With CDC, the host isn't allowed to use these two data |
@@ -2278,10 +2340,10 @@ eth_bind (struct usb_gadget *gadget) | |||
2278 | "RNDIS/%s", driver_desc); | 2340 | "RNDIS/%s", driver_desc); |
2279 | 2341 | ||
2280 | /* CDC subset ... recognized by Linux since 2.4.10, but Windows | 2342 | /* CDC subset ... recognized by Linux since 2.4.10, but Windows |
2281 | * drivers aren't widely available. | 2343 | * drivers aren't widely available. (That may be improved by |
2344 | * supporting one submode of the "SAFE" variant of MDLM.) | ||
2282 | */ | 2345 | */ |
2283 | } else if (!cdc) { | 2346 | } else if (!cdc) { |
2284 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | ||
2285 | device_desc.idVendor = | 2347 | device_desc.idVendor = |
2286 | __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); | 2348 | __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); |
2287 | device_desc.idProduct = | 2349 | device_desc.idProduct = |
@@ -2352,6 +2414,10 @@ autoconf_fail: | |||
2352 | if (!cdc) { | 2414 | if (!cdc) { |
2353 | eth_config.bNumInterfaces = 1; | 2415 | eth_config.bNumInterfaces = 1; |
2354 | eth_config.iConfiguration = STRING_SUBSET; | 2416 | eth_config.iConfiguration = STRING_SUBSET; |
2417 | |||
2418 | /* use functions to set these up, in case we're built to work | ||
2419 | * with multiple controllers and must override CDC Ethernet. | ||
2420 | */ | ||
2355 | fs_subset_descriptors(); | 2421 | fs_subset_descriptors(); |
2356 | hs_subset_descriptors(); | 2422 | hs_subset_descriptors(); |
2357 | } | 2423 | } |
@@ -2415,22 +2481,20 @@ autoconf_fail: | |||
2415 | 2481 | ||
2416 | /* Module params for these addresses should come from ID proms. | 2482 | /* Module params for these addresses should come from ID proms. |
2417 | * The host side address is used with CDC and RNDIS, and commonly | 2483 | * The host side address is used with CDC and RNDIS, and commonly |
2418 | * ends up in a persistent config database. | 2484 | * ends up in a persistent config database. It's not clear if |
2485 | * host side code for the SAFE thing cares -- its original BLAN | ||
2486 | * thing didn't, Sharp never assigned those addresses on Zaurii. | ||
2419 | */ | 2487 | */ |
2420 | if (get_ether_addr(dev_addr, net->dev_addr)) | 2488 | if (get_ether_addr(dev_addr, net->dev_addr)) |
2421 | dev_warn(&gadget->dev, | 2489 | dev_warn(&gadget->dev, |
2422 | "using random %s ethernet address\n", "self"); | 2490 | "using random %s ethernet address\n", "self"); |
2423 | if (cdc || rndis) { | 2491 | if (get_ether_addr(host_addr, dev->host_mac)) |
2424 | if (get_ether_addr(host_addr, dev->host_mac)) | 2492 | dev_warn(&gadget->dev, |
2425 | dev_warn(&gadget->dev, | 2493 | "using random %s ethernet address\n", "host"); |
2426 | "using random %s ethernet address\n", "host"); | 2494 | snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", |
2427 | #ifdef DEV_CONFIG_CDC | 2495 | dev->host_mac [0], dev->host_mac [1], |
2428 | snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", | 2496 | dev->host_mac [2], dev->host_mac [3], |
2429 | dev->host_mac [0], dev->host_mac [1], | 2497 | dev->host_mac [4], dev->host_mac [5]); |
2430 | dev->host_mac [2], dev->host_mac [3], | ||
2431 | dev->host_mac [4], dev->host_mac [5]); | ||
2432 | #endif | ||
2433 | } | ||
2434 | 2498 | ||
2435 | if (rndis) { | 2499 | if (rndis) { |
2436 | status = rndis_init(); | 2500 | status = rndis_init(); |