ncm.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * ncm.c -- NCM gadget driver
  4. *
  5. * Copyright (C) 2010 Nokia Corporation
  6. * Contact: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
  7. *
  8. * The driver borrows from ether.c which is:
  9. *
  10. * Copyright (C) 2003-2005,2008 David Brownell
  11. * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  12. * Copyright (C) 2008 Nokia Corporation
  13. */
  14. /* #define DEBUG */
  15. /* #define VERBOSE_DEBUG */
  16. #include <linux/kernel.h>
  17. #include <linux/module.h>
  18. #include <linux/usb/composite.h>
  19. #include "u_ether.h"
  20. #include "u_ncm.h"
  21. #define DRIVER_DESC "NCM Gadget"
  22. /*-------------------------------------------------------------------------*/
  23. /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
  24. * Instead: allocate your own, using normal USB-IF procedures.
  25. */
  26. /* Thanks to NetChip Technologies for donating this product ID.
  27. * It's for devices with only CDC Ethernet configurations.
  28. */
  29. #define CDC_VENDOR_NUM 0x0525 /* NetChip */
  30. #define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */
  31. /*-------------------------------------------------------------------------*/
  32. USB_GADGET_COMPOSITE_OPTIONS();
  33. USB_ETHERNET_MODULE_PARAMETERS();
  34. static struct usb_device_descriptor device_desc = {
  35. .bLength = sizeof device_desc,
  36. .bDescriptorType = USB_DT_DEVICE,
  37. /* .bcdUSB = DYNAMIC */
  38. .bDeviceClass = USB_CLASS_COMM,
  39. .bDeviceSubClass = 0,
  40. .bDeviceProtocol = 0,
  41. /* .bMaxPacketSize0 = f(hardware) */
  42. /* Vendor and product id defaults change according to what configs
  43. * we support. (As does bNumConfigurations.) These values can
  44. * also be overridden by module parameters.
  45. */
  46. .idVendor = cpu_to_le16 (CDC_VENDOR_NUM),
  47. .idProduct = cpu_to_le16 (CDC_PRODUCT_NUM),
  48. /* .bcdDevice = f(hardware) */
  49. /* .iManufacturer = DYNAMIC */
  50. /* .iProduct = DYNAMIC */
  51. /* NO SERIAL NUMBER */
  52. .bNumConfigurations = 1,
  53. };
  54. static const struct usb_descriptor_header *otg_desc[2];
  55. /* string IDs are assigned dynamically */
  56. static struct usb_string strings_dev[] = {
  57. [USB_GADGET_MANUFACTURER_IDX].s = "",
  58. [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC,
  59. [USB_GADGET_SERIAL_IDX].s = "",
  60. { } /* end of list */
  61. };
  62. static struct usb_gadget_strings stringtab_dev = {
  63. .language = 0x0409, /* en-us */
  64. .strings = strings_dev,
  65. };
  66. static struct usb_gadget_strings *dev_strings[] = {
  67. &stringtab_dev,
  68. NULL,
  69. };
  70. static struct usb_function_instance *f_ncm_inst;
  71. static struct usb_function *f_ncm;
  72. /*-------------------------------------------------------------------------*/
  73. static int ncm_do_config(struct usb_configuration *c)
  74. {
  75. int status;
  76. /* FIXME alloc iConfiguration string, set it in c->strings */
  77. if (gadget_is_otg(c->cdev->gadget)) {
  78. c->descriptors = otg_desc;
  79. c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
  80. }
  81. f_ncm = usb_get_function(f_ncm_inst);
  82. if (IS_ERR(f_ncm))
  83. return PTR_ERR(f_ncm);
  84. status = usb_add_function(c, f_ncm);
  85. if (status < 0) {
  86. usb_put_function(f_ncm);
  87. return status;
  88. }
  89. return 0;
  90. }
  91. static struct usb_configuration ncm_config_driver = {
  92. /* .label = f(hardware) */
  93. .label = "CDC Ethernet (NCM)",
  94. .bConfigurationValue = 1,
  95. /* .iConfiguration = DYNAMIC */
  96. .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
  97. };
  98. /*-------------------------------------------------------------------------*/
  99. static int gncm_bind(struct usb_composite_dev *cdev)
  100. {
  101. struct usb_gadget *gadget = cdev->gadget;
  102. struct f_ncm_opts *ncm_opts;
  103. int status;
  104. f_ncm_inst = usb_get_function_instance("ncm");
  105. if (IS_ERR(f_ncm_inst))
  106. return PTR_ERR(f_ncm_inst);
  107. ncm_opts = container_of(f_ncm_inst, struct f_ncm_opts, func_inst);
  108. gether_set_qmult(ncm_opts->net, qmult);
  109. if (!gether_set_host_addr(ncm_opts->net, host_addr))
  110. pr_info("using host ethernet address: %s", host_addr);
  111. if (!gether_set_dev_addr(ncm_opts->net, dev_addr))
  112. pr_info("using self ethernet address: %s", dev_addr);
  113. /* Allocate string descriptor numbers ... note that string
  114. * contents can be overridden by the composite_dev glue.
  115. */
  116. status = usb_string_ids_tab(cdev, strings_dev);
  117. if (status < 0)
  118. goto fail;
  119. device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
  120. device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
  121. if (gadget_is_otg(gadget) && !otg_desc[0]) {
  122. struct usb_descriptor_header *usb_desc;
  123. usb_desc = usb_otg_descriptor_alloc(gadget);
  124. if (!usb_desc)
  125. goto fail;
  126. usb_otg_descriptor_init(gadget, usb_desc);
  127. otg_desc[0] = usb_desc;
  128. otg_desc[1] = NULL;
  129. }
  130. status = usb_add_config(cdev, &ncm_config_driver,
  131. ncm_do_config);
  132. if (status < 0)
  133. goto fail1;
  134. usb_composite_overwrite_options(cdev, &coverwrite);
  135. dev_info(&gadget->dev, "%s\n", DRIVER_DESC);
  136. return 0;
  137. fail1:
  138. kfree(otg_desc[0]);
  139. otg_desc[0] = NULL;
  140. fail:
  141. usb_put_function_instance(f_ncm_inst);
  142. return status;
  143. }
  144. static int gncm_unbind(struct usb_composite_dev *cdev)
  145. {
  146. if (!IS_ERR_OR_NULL(f_ncm))
  147. usb_put_function(f_ncm);
  148. if (!IS_ERR_OR_NULL(f_ncm_inst))
  149. usb_put_function_instance(f_ncm_inst);
  150. kfree(otg_desc[0]);
  151. otg_desc[0] = NULL;
  152. return 0;
  153. }
  154. static struct usb_composite_driver ncm_driver = {
  155. .name = "g_ncm",
  156. .dev = &device_desc,
  157. .strings = dev_strings,
  158. .max_speed = USB_SPEED_SUPER,
  159. .bind = gncm_bind,
  160. .unbind = gncm_unbind,
  161. };
  162. module_usb_composite_driver(ncm_driver);
  163. MODULE_DESCRIPTION(DRIVER_DESC);
  164. MODULE_AUTHOR("Yauheni Kaliuta");
  165. MODULE_LICENSE("GPL");