qmi_wwan.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright (c) 2012 Bjørn Mork <bjorn@mork.no>
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * version 2 as published by the Free Software Foundation.
  7. */
  8. #include <linux/module.h>
  9. #include <linux/netdevice.h>
  10. #include <linux/ethtool.h>
  11. #include <linux/mii.h>
  12. #include <linux/usb.h>
  13. #include <linux/usb/cdc.h>
  14. #include <linux/usb/usbnet.h>
  15. /* The name of the CDC Device Management driver */
  16. #define DM_DRIVER "cdc_wdm"
  17. /*
  18. * This driver supports wwan (3G/LTE/?) devices using a vendor
  19. * specific management protocol called Qualcomm MSM Interface (QMI) -
  20. * in addition to the more common AT commands over serial interface
  21. * management
  22. *
  23. * QMI is wrapped in CDC, using CDC encapsulated commands on the
  24. * control ("master") interface of a two-interface CDC Union
  25. * resembling standard CDC ECM. The devices do not use the control
  26. * interface for any other CDC messages. Most likely because the
  27. * management protocol is used in place of the standard CDC
  28. * notifications NOTIFY_NETWORK_CONNECTION and NOTIFY_SPEED_CHANGE
  29. *
  30. * Handling a protocol like QMI is out of the scope for any driver.
  31. * It can be exported as a character device using the cdc-wdm driver,
  32. * which will enable userspace applications ("modem managers") to
  33. * handle it. This may be required to use the network interface
  34. * provided by the driver.
  35. *
  36. * These devices may alternatively/additionally be configured using AT
  37. * commands on any of the serial interfaces driven by the option driver
  38. *
  39. * This driver binds only to the data ("slave") interface to enable
  40. * the cdc-wdm driver to bind to the control interface. It still
  41. * parses the CDC functional descriptors on the control interface to
  42. * a) verify that this is indeed a handled interface (CDC Union
  43. * header lists it as slave)
  44. * b) get MAC address and other ethernet config from the CDC Ethernet
  45. * header
  46. * c) enable user bind requests against the control interface, which
  47. * is the common way to bind to CDC Ethernet Control Model type
  48. * interfaces
  49. * d) provide a hint to the user about which interface is the
  50. * corresponding management interface
  51. */
  52. static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
  53. {
  54. int status = -1;
  55. struct usb_interface *control = NULL;
  56. u8 *buf = intf->cur_altsetting->extra;
  57. int len = intf->cur_altsetting->extralen;
  58. struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
  59. struct usb_cdc_union_desc *cdc_union = NULL;
  60. struct usb_cdc_ether_desc *cdc_ether = NULL;
  61. u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE;
  62. u32 found = 0;
  63. /*
  64. * assume a data interface has no additional descriptors and
  65. * that the control and data interface are numbered
  66. * consecutively - this holds for the Huawei device at least
  67. */
  68. if (len == 0 && desc->bInterfaceNumber > 0) {
  69. control = usb_ifnum_to_if(dev->udev, desc->bInterfaceNumber - 1);
  70. if (!control)
  71. goto err;
  72. buf = control->cur_altsetting->extra;
  73. len = control->cur_altsetting->extralen;
  74. dev_dbg(&intf->dev, "guessing \"control\" => %s, \"data\" => this\n",
  75. dev_name(&control->dev));
  76. }
  77. while (len > 3) {
  78. struct usb_descriptor_header *h = (void *)buf;
  79. /* ignore any misplaced descriptors */
  80. if (h->bDescriptorType != USB_DT_CS_INTERFACE)
  81. goto next_desc;
  82. /* buf[2] is CDC descriptor subtype */
  83. switch (buf[2]) {
  84. case USB_CDC_HEADER_TYPE:
  85. if (found & 1 << USB_CDC_HEADER_TYPE) {
  86. dev_dbg(&intf->dev, "extra CDC header\n");
  87. goto err;
  88. }
  89. if (h->bLength != sizeof(struct usb_cdc_header_desc)) {
  90. dev_dbg(&intf->dev, "CDC header len %u\n", h->bLength);
  91. goto err;
  92. }
  93. break;
  94. case USB_CDC_UNION_TYPE:
  95. if (found & 1 << USB_CDC_UNION_TYPE) {
  96. dev_dbg(&intf->dev, "extra CDC union\n");
  97. goto err;
  98. }
  99. if (h->bLength != sizeof(struct usb_cdc_union_desc)) {
  100. dev_dbg(&intf->dev, "CDC union len %u\n", h->bLength);
  101. goto err;
  102. }
  103. cdc_union = (struct usb_cdc_union_desc *)buf;
  104. break;
  105. case USB_CDC_ETHERNET_TYPE:
  106. if (found & 1 << USB_CDC_ETHERNET_TYPE) {
  107. dev_dbg(&intf->dev, "extra CDC ether\n");
  108. goto err;
  109. }
  110. if (h->bLength != sizeof(struct usb_cdc_ether_desc)) {
  111. dev_dbg(&intf->dev, "CDC ether len %u\n", h->bLength);
  112. goto err;
  113. }
  114. cdc_ether = (struct usb_cdc_ether_desc *)buf;
  115. break;
  116. }
  117. /*
  118. * Remember which CDC functional descriptors we've seen. Works
  119. * for all types we care about, of which USB_CDC_ETHERNET_TYPE
  120. * (0x0f) is the highest numbered
  121. */
  122. if (buf[2] < 32)
  123. found |= 1 << buf[2];
  124. next_desc:
  125. len -= h->bLength;
  126. buf += h->bLength;
  127. }
  128. /* did we find all the required ones? */
  129. if ((found & required) != required) {
  130. dev_err(&intf->dev, "CDC functional descriptors missing\n");
  131. goto err;
  132. }
  133. /* give the user a helpful hint if trying to bind to the wrong interface */
  134. if (cdc_union && desc->bInterfaceNumber == cdc_union->bMasterInterface0) {
  135. dev_err(&intf->dev, "leaving \"control\" interface for " DM_DRIVER " - try binding to %s instead!\n",
  136. dev_name(&usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0)->dev));
  137. goto err;
  138. }
  139. /* errors aren't fatal - we can live with the dynamic address */
  140. if (cdc_ether) {
  141. dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize);
  142. usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress);
  143. }
  144. /* success! point the user to the management interface */
  145. if (control)
  146. dev_info(&intf->dev, "Use \"" DM_DRIVER "\" for QMI interface %s\n",
  147. dev_name(&control->dev));
  148. /* XXX: add a sysfs symlink somewhere to help management applications find it? */
  149. /* collect bulk endpoints now that we know intf == "data" interface */
  150. status = usbnet_get_endpoints(dev, intf);
  151. err:
  152. return status;
  153. }
  154. /* stolen from cdc_ether.c */
  155. static int qmi_wwan_manage_power(struct usbnet *dev, int on)
  156. {
  157. dev->intf->needs_remote_wakeup = on;
  158. return 0;
  159. }
  160. static const struct driver_info qmi_wwan_info = {
  161. .description = "QMI speaking wwan device",
  162. .flags = FLAG_WWAN,
  163. .bind = qmi_wwan_bind,
  164. .manage_power = qmi_wwan_manage_power,
  165. };
  166. #define HUAWEI_VENDOR_ID 0x12D1
  167. static const struct usb_device_id products[] = {
  168. {
  169. /* Huawei E392, E398 and possibly others sharing both device id and more... */
  170. .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
  171. .idVendor = HUAWEI_VENDOR_ID,
  172. .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
  173. .bInterfaceSubClass = 1,
  174. .bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */
  175. .driver_info = (unsigned long)&qmi_wwan_info,
  176. }, {
  177. }, /* END */
  178. };
  179. MODULE_DEVICE_TABLE(usb, products);
  180. static struct usb_driver qmi_wwan_driver = {
  181. .name = "qmi_wwan",
  182. .id_table = products,
  183. .probe = usbnet_probe,
  184. .disconnect = usbnet_disconnect,
  185. .suspend = usbnet_suspend,
  186. .resume = usbnet_resume,
  187. .reset_resume = usbnet_resume,
  188. .supports_autosuspend = 1,
  189. };
  190. static int __init qmi_wwan_init(void)
  191. {
  192. return usb_register(&qmi_wwan_driver);
  193. }
  194. module_init(qmi_wwan_init);
  195. static void __exit qmi_wwan_exit(void)
  196. {
  197. usb_deregister(&qmi_wwan_driver);
  198. }
  199. module_exit(qmi_wwan_exit);
  200. MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>");
  201. MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver");
  202. MODULE_LICENSE("GPL");