f_ncm.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546
  1. #include "usb_os_adapter.h"
  2. #include "board.h"
  3. #include <linux/usb/cdc.h>
  4. #include "linux/usb/composite.h"
  5. #include "linux/usb/ether.h"
  6. #include <stdio.h>
  7. #include "include/crc.h"
  8. #include "timers.h"
  9. #include "trace.h"
  10. #include "NetworkBufferManagement.h"
  11. #if USE_LWIP
  12. #include "lwip/pbuf.h"
  13. #endif
  14. /* to trigger crc/non-crc ndp signature */
  15. #define VDBG(d, fmt, args...) \
  16. dev_vdbg(&(d)->gadget->dev , fmt , ## args)
  17. #define DBG(d, fmt, args...) \
  18. dev_vdbg(&(d)->gadget->dev , fmt , ## args)
  19. #define ERROR(d, fmt, args...) \
  20. dev_err(&(d)->gadget->dev , fmt , ## args)
  21. #define INFO(d, fmt, args...) \
  22. dev_info(&(d)->gadget->dev , fmt , ## args)
  23. #define NCM_NDP_HDR_CRC_MASK 0x01000000
  24. #define NCM_NDP_HDR_CRC 0x01000000
  25. #define NCM_NDP_HDR_NOCRC 0x00000000
  26. #define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
  27. |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
  28. |USB_CDC_PACKET_TYPE_PROMISCUOUS \
  29. |USB_CDC_PACKET_TYPE_DIRECTED)
  30. enum ncm_notify_state {
  31. NCM_NOTIFY_NONE, /* don't notify */
  32. NCM_NOTIFY_CONNECT, /* issue CONNECT next */
  33. NCM_NOTIFY_SPEED, /* issue SPEED_CHANGE next */
  34. };
  35. struct f_ncm {
  36. struct gether port;
  37. u8 ctrl_id, data_id;
  38. char ethaddr[14];
  39. struct usb_ep *notify;
  40. struct usb_request *notify_req;
  41. u8 notify_state;
  42. bool is_open;
  43. struct ndp_parser_opts *parser_opts;
  44. bool is_crc;
  45. /*
  46. * for notification, it is accessed from both
  47. * callback and ethernet open/close
  48. */
  49. spinlock_t lock;
  50. bool connect;
  51. TimerHandle_t timer;
  52. };
  53. static inline struct f_ncm *func_to_ncm(struct usb_function *f)
  54. {
  55. return (struct f_ncm *)f->powner;
  56. }
  57. /* peak (theoretical) bulk transfer rate in bits-per-second */
  58. static inline unsigned ncm_bitrate(struct usb_gadget *g)
  59. {
  60. if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
  61. return 13 * 512 * 8 * 1000 * 8;
  62. else
  63. return 19 * 64 * 1 * 1000 * 8;
  64. }
  65. /*-------------------------------------------------------------------------*/
  66. /*
  67. * We cannot group frames so use just the minimal size which ok to put
  68. * one max-size ethernet frame.
  69. * If the host can group frames, allow it to do that, 16K is selected,
  70. * because it's used by default by the current linux host driver
  71. */
  72. #define NTB_DEFAULT_IN_SIZE 2048//USB_CDC_NCM_NTB_MIN_IN_SIZE
  73. #define NTB_OUT_SIZE 3072
  74. /*
  75. * skbs of size less than that will not be aligned
  76. * to NCM's dwNtbInMaxSize to save bus bandwidth
  77. */
  78. #define MAX_TX_NONFIXED (512 * 3)
  79. #define FORMATS_SUPPORTED (USB_CDC_NCM_NTB16_SUPPORTED | \
  80. USB_CDC_NCM_NTB32_SUPPORTED)
  81. static struct usb_cdc_ncm_ntb_parameters ntb_parameters = {
  82. .wLength = sizeof ntb_parameters,
  83. .bmNtbFormatsSupported = cpu_to_le16(FORMATS_SUPPORTED),
  84. .dwNtbInMaxSize = cpu_to_le32(NTB_DEFAULT_IN_SIZE),
  85. .wNdpInDivisor = cpu_to_le16(4),
  86. .wNdpInPayloadRemainder = cpu_to_le16(0),
  87. .wNdpInAlignment = cpu_to_le16(4),
  88. .dwNtbOutMaxSize = cpu_to_le32(NTB_OUT_SIZE),
  89. .wNdpOutDivisor = cpu_to_le16(4),
  90. .wNdpOutPayloadRemainder = cpu_to_le16(0),
  91. .wNdpOutAlignment = cpu_to_le16(4),
  92. //.wNtbOutMaxDatagrams = cpu_to_le16(32),
  93. };
  94. /*
  95. * Use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
  96. * packet, to simplify cancellation; and a big transfer interval, to
  97. * waste less bandwidth.
  98. */
  99. #define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
  100. #define NCM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
  101. static struct usb_interface_assoc_descriptor ncm_iad_desc = {
  102. .bLength = sizeof ncm_iad_desc,
  103. .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
  104. /* .bFirstInterface = DYNAMIC, */
  105. .bInterfaceCount = 2, /* control + data */
  106. .bFunctionClass = USB_CLASS_COMM,
  107. .bFunctionSubClass = USB_CDC_SUBCLASS_NCM,
  108. .bFunctionProtocol = USB_CDC_PROTO_NONE,
  109. /* .iFunction = DYNAMIC */
  110. };
  111. /* interface descriptor: */
  112. static struct usb_interface_descriptor ncm_control_intf = {
  113. .bLength = sizeof ncm_control_intf,
  114. .bDescriptorType = USB_DT_INTERFACE,
  115. /* .bInterfaceNumber = DYNAMIC */
  116. .bNumEndpoints = 1,
  117. .bInterfaceClass = USB_CLASS_COMM,
  118. .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM,
  119. .bInterfaceProtocol = USB_CDC_PROTO_NONE,
  120. /* .iInterface = DYNAMIC */
  121. };
  122. static struct usb_cdc_header_desc ncm_header_desc = {
  123. .bLength = sizeof ncm_header_desc,
  124. .bDescriptorType = USB_DT_CS_INTERFACE,
  125. .bDescriptorSubType = USB_CDC_HEADER_TYPE,
  126. .bcdCDC = cpu_to_le16(0x0110),
  127. };
  128. static struct usb_cdc_union_desc ncm_union_desc = {
  129. .bLength = sizeof(ncm_union_desc),
  130. .bDescriptorType = USB_DT_CS_INTERFACE,
  131. .bDescriptorSubType = USB_CDC_UNION_TYPE,
  132. /* .bMasterInterface0 = DYNAMIC */
  133. /* .bSlaveInterface0 = DYNAMIC */
  134. };
  135. static struct usb_cdc_ether_desc ecm_desc = {
  136. .bLength = sizeof ecm_desc,
  137. .bDescriptorType = USB_DT_CS_INTERFACE,
  138. .bDescriptorSubType = USB_CDC_ETHERNET_TYPE,
  139. /* this descriptor actually adds value, surprise! */
  140. /* .iMACAddress = DYNAMIC */
  141. .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
  142. .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN * 8),
  143. .wNumberMCFilters = cpu_to_le16(0),
  144. .bNumberPowerFilters = 0,
  145. };
  146. #define NCAPS (USB_CDC_NCM_NCAP_ETH_FILTER | USB_CDC_NCM_NCAP_CRC_MODE)
  147. static struct usb_cdc_ncm_desc ncm_desc = {
  148. .bLength = sizeof ncm_desc,
  149. .bDescriptorType = USB_DT_CS_INTERFACE,
  150. .bDescriptorSubType = USB_CDC_NCM_TYPE,
  151. .bcdNcmVersion = cpu_to_le16(0x0100),
  152. /* can process SetEthernetPacketFilter */
  153. .bmNetworkCapabilities = 0x3A,//NCAPS,//,
  154. };
  155. /* the default data interface has no endpoints ... */
  156. static struct usb_interface_descriptor ncm_data_nop_intf = {
  157. .bLength = sizeof ncm_data_nop_intf,
  158. .bDescriptorType = USB_DT_INTERFACE,
  159. .bInterfaceNumber = 1,
  160. .bAlternateSetting = 0,
  161. .bNumEndpoints = 0,
  162. .bInterfaceClass = USB_CLASS_CDC_DATA,
  163. .bInterfaceSubClass = 0,
  164. .bInterfaceProtocol = USB_CDC_NCM_PROTO_NTB,
  165. /* .iInterface = DYNAMIC */
  166. };
  167. /* ... but the "real" data interface has two bulk endpoints */
  168. static struct usb_interface_descriptor ncm_data_intf = {
  169. .bLength = sizeof ncm_data_intf,
  170. .bDescriptorType = USB_DT_INTERFACE,
  171. .bInterfaceNumber = 1,
  172. .bAlternateSetting = 1,
  173. .bNumEndpoints = 2,
  174. .bInterfaceClass = USB_CLASS_CDC_DATA,
  175. .bInterfaceSubClass = 0,
  176. .bInterfaceProtocol = USB_CDC_NCM_PROTO_NTB,
  177. /* .iInterface = DYNAMIC */
  178. };
  179. /* full speed support: */
  180. static struct usb_endpoint_descriptor fs_ncm_notify_desc = {
  181. .bLength = USB_DT_ENDPOINT_SIZE,
  182. .bDescriptorType = USB_DT_ENDPOINT,
  183. .bEndpointAddress = USB_DIR_IN,
  184. .bmAttributes = USB_ENDPOINT_XFER_INT,
  185. .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT),
  186. .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
  187. };
  188. static struct usb_endpoint_descriptor fs_ncm_in_desc = {
  189. .bLength = USB_DT_ENDPOINT_SIZE,
  190. .bDescriptorType = USB_DT_ENDPOINT,
  191. .bEndpointAddress = USB_DIR_IN,
  192. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  193. };
  194. static struct usb_endpoint_descriptor fs_ncm_out_desc = {
  195. .bLength = USB_DT_ENDPOINT_SIZE,
  196. .bDescriptorType = USB_DT_ENDPOINT,
  197. .bEndpointAddress = USB_DIR_OUT,
  198. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  199. };
  200. static struct usb_descriptor_header *ncm_fs_function[] = {
  201. (struct usb_descriptor_header *) &ncm_iad_desc,
  202. /* CDC NCM control descriptors */
  203. (struct usb_descriptor_header *) &ncm_control_intf,
  204. (struct usb_descriptor_header *) &ncm_header_desc,
  205. (struct usb_descriptor_header *) &ncm_union_desc,
  206. (struct usb_descriptor_header *) &ecm_desc,
  207. (struct usb_descriptor_header *) &ncm_desc,
  208. (struct usb_descriptor_header *) &fs_ncm_notify_desc,
  209. /* data interface, altsettings 0 and 1 */
  210. (struct usb_descriptor_header *) &ncm_data_nop_intf,
  211. (struct usb_descriptor_header *) &ncm_data_intf,
  212. (struct usb_descriptor_header *) &fs_ncm_in_desc,
  213. (struct usb_descriptor_header *) &fs_ncm_out_desc,
  214. NULL,
  215. };
  216. /* high speed support: */
  217. static struct usb_endpoint_descriptor hs_ncm_notify_desc = {
  218. .bLength = USB_DT_ENDPOINT_SIZE,
  219. .bDescriptorType = USB_DT_ENDPOINT,
  220. .bEndpointAddress = USB_DIR_IN,
  221. .bmAttributes = USB_ENDPOINT_XFER_INT,
  222. .wMaxPacketSize = cpu_to_le16(64),//NCM_STATUS_BYTECOUNT
  223. .bInterval = 2,//LOG2_STATUS_INTERVAL_MSEC + 4,
  224. };
  225. static struct usb_endpoint_descriptor hs_ncm_in_desc = {
  226. .bLength = USB_DT_ENDPOINT_SIZE,
  227. .bDescriptorType = USB_DT_ENDPOINT,
  228. .bEndpointAddress = USB_DIR_IN,
  229. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  230. .wMaxPacketSize = cpu_to_le16(512),
  231. };
  232. static struct usb_endpoint_descriptor hs_ncm_out_desc = {
  233. .bLength = USB_DT_ENDPOINT_SIZE,
  234. .bDescriptorType = USB_DT_ENDPOINT,
  235. .bEndpointAddress = USB_DIR_OUT,
  236. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  237. .wMaxPacketSize = cpu_to_le16(512),
  238. };
  239. static struct usb_descriptor_header *ncm_hs_function[] = {
  240. (struct usb_descriptor_header *) &ncm_iad_desc,
  241. /* CDC NCM control descriptors */
  242. (struct usb_descriptor_header *) &ncm_control_intf,
  243. (struct usb_descriptor_header *) &ncm_header_desc,
  244. (struct usb_descriptor_header *) &ncm_union_desc,
  245. (struct usb_descriptor_header *) &ecm_desc,
  246. (struct usb_descriptor_header *) &ncm_desc,
  247. (struct usb_descriptor_header *) &hs_ncm_notify_desc,
  248. /* data interface, altsettings 0 and 1 */
  249. (struct usb_descriptor_header *) &ncm_data_nop_intf,
  250. (struct usb_descriptor_header *) &ncm_data_intf,
  251. (struct usb_descriptor_header *) &hs_ncm_in_desc,
  252. (struct usb_descriptor_header *) &hs_ncm_out_desc,
  253. NULL,
  254. };
  255. /* string descriptors: */
  256. #define STRING_CTRL_IDX 0
  257. #define STRING_MAC_IDX 1
  258. #define STRING_DATA_IDX 2
  259. #define STRING_IAD_IDX 3
  260. static struct usb_string ncm_string_defs[] = {
  261. [STRING_CTRL_IDX].s = "CDC Network Control Model (NCM)",
  262. [STRING_MAC_IDX].s = NULL /* DYNAMIC */,
  263. [STRING_DATA_IDX].s = "CDC Network Data",
  264. [STRING_IAD_IDX].s = "CDC NCM",
  265. };
  266. static struct usb_gadget_strings ncm_string_table = {
  267. .language = 0x0409, /* en-us */
  268. .strings = ncm_string_defs,
  269. };
  270. static struct usb_gadget_strings *ncm_strings[] = {
  271. &ncm_string_table,
  272. NULL,
  273. };
  274. /*
  275. * Here are options for NCM Datagram Pointer table (NDP) parser.
  276. * There are 2 different formats: NDP16 and NDP32 in the spec (ch. 3),
  277. * in NDP16 offsets and sizes fields are 1 16bit word wide,
  278. * in NDP32 -- 2 16bit words wide. Also signatures are different.
  279. * To make the parser code the same, put the differences in the structure,
  280. * and switch pointers to the structures when the format is changed.
  281. */
  282. struct ndp_parser_opts {
  283. u32 nth_sign;
  284. u32 ndp_sign;
  285. unsigned nth_size;
  286. unsigned ndp_size;
  287. unsigned ndplen_align;
  288. /* sizes in u16 units */
  289. unsigned dgram_item_len; /* index or length */
  290. unsigned block_length;
  291. unsigned fp_index;
  292. unsigned reserved1;
  293. unsigned reserved2;
  294. unsigned next_fp_index;
  295. };
  296. #define INIT_NDP16_OPTS { \
  297. .nth_sign = USB_CDC_NCM_NTH16_SIGN, \
  298. .ndp_sign = USB_CDC_NCM_NDP16_NOCRC_SIGN, \
  299. .nth_size = sizeof(struct usb_cdc_ncm_nth16), \
  300. .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \
  301. .ndplen_align = 4, \
  302. .dgram_item_len = 1, \
  303. .block_length = 1, \
  304. .fp_index = 1, \
  305. .reserved1 = 0, \
  306. .reserved2 = 0, \
  307. .next_fp_index = 1, \
  308. }
  309. #define INIT_NDP32_OPTS { \
  310. .nth_sign = USB_CDC_NCM_NTH32_SIGN, \
  311. .ndp_sign = USB_CDC_NCM_NDP32_NOCRC_SIGN, \
  312. .nth_size = sizeof(struct usb_cdc_ncm_nth32), \
  313. .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \
  314. .ndplen_align = 8, \
  315. .dgram_item_len = 2, \
  316. .block_length = 2, \
  317. .fp_index = 2, \
  318. .reserved1 = 1, \
  319. .reserved2 = 2, \
  320. .next_fp_index = 2, \
  321. }
  322. static struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS;
  323. static struct ndp_parser_opts ndp32_opts = INIT_NDP32_OPTS;
  324. static inline void put_ncm(__le16 **p, unsigned size, unsigned val)
  325. {
  326. switch (size) {
  327. case 1:
  328. put_unaligned_le16((u16)val, *p);
  329. break;
  330. case 2:
  331. put_unaligned_le32((u32)val, *p);
  332. break;
  333. default:
  334. BUG();
  335. }
  336. *p += size;
  337. }
  338. static inline unsigned get_ncm(__le16 **p, unsigned size)
  339. {
  340. unsigned tmp;
  341. switch (size) {
  342. case 1:
  343. tmp = get_unaligned_le16(*p);
  344. break;
  345. case 2:
  346. tmp = get_unaligned_le32(*p);
  347. break;
  348. default:
  349. BUG();
  350. }
  351. *p += size;
  352. return tmp;
  353. }
  354. /*-------------------------------------------------------------------------*/
  355. static inline void ncm_reset_values(struct f_ncm *ncm)
  356. {
  357. ncm->parser_opts = &ndp16_opts;
  358. ncm->is_crc = false;
  359. ncm->port.cdc_filter = DEFAULT_FILTER;
  360. /* doesn't make sense for ncm, fixed size used */
  361. ncm->port.header_len = 0;
  362. ncm->port.fixed_out_len = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize);
  363. ncm->port.fixed_in_len = NTB_DEFAULT_IN_SIZE;
  364. }
  365. /*
  366. * Context: ncm->lock held
  367. */
  368. static void ncm_do_notify(struct f_ncm *ncm)
  369. {
  370. struct usb_request *req = ncm->notify_req;
  371. struct usb_cdc_notification *event;
  372. struct usb_composite_dev *cdev = ncm->port.func.config->cdev;
  373. __le32 *data;
  374. int status;
  375. /* notification already in flight? */
  376. if (!req)
  377. return;
  378. event = req->buf;
  379. switch (ncm->notify_state) {
  380. case NCM_NOTIFY_NONE:
  381. return;
  382. case NCM_NOTIFY_CONNECT:
  383. event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION;
  384. if (ncm->is_open)
  385. event->wValue = cpu_to_le16(1);
  386. else
  387. event->wValue = cpu_to_le16(0);
  388. event->wLength = 0;
  389. req->length = sizeof *event;
  390. DBG(cdev, "notify connect %s\n",
  391. ncm->is_open ? "true" : "false");
  392. ncm->notify_state = NCM_NOTIFY_NONE;
  393. break;
  394. case NCM_NOTIFY_SPEED:
  395. event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE;
  396. event->wValue = cpu_to_le16(0);
  397. event->wLength = cpu_to_le16(8);
  398. req->length = NCM_STATUS_BYTECOUNT;
  399. /* SPEED_CHANGE data is up/down speeds in bits/sec */
  400. data = (__le32 *)((uint8_t*)req->buf + sizeof *event);
  401. data[0] = cpu_to_le32(ncm_bitrate(cdev->gadget));
  402. data[1] = data[0];
  403. printf("notify speed %d\r\n", ncm_bitrate(cdev->gadget));
  404. ncm->notify_state = NCM_NOTIFY_CONNECT;
  405. break;
  406. }
  407. event->bmRequestType = 0xA1;
  408. event->wIndex = cpu_to_le16(ncm->ctrl_id);
  409. ncm->notify_req = NULL;
  410. /*
  411. * In double buffering if there is a space in FIFO,
  412. * completion callback can be called right after the call,
  413. * so unlocking
  414. */
  415. //spin_unlock(&ncm->lock);
  416. status = usb_ep_queue(ncm->notify, req, GFP_ATOMIC);
  417. //spin_lock(&ncm->lock);
  418. if (status < 0) {
  419. ncm->notify_req = req;
  420. DBG(cdev, "notify --> %d\n", status);
  421. }
  422. }
  423. /*
  424. * Context: ncm->lock held
  425. */
  426. static void ncm_notify(struct f_ncm *ncm)
  427. {
  428. /*
  429. * NOTE on most versions of Linux, host side cdc-ethernet
  430. * won't listen for notifications until its netdevice opens.
  431. * The first notification then sits in the FIFO for a long
  432. * time, and the second one is queued.
  433. *
  434. * If ncm_notify() is called before the second (CONNECT)
  435. * notification is sent, then it will reset to send the SPEED
  436. * notificaion again (and again, and again), but it's not a problem
  437. */
  438. ncm->notify_state = NCM_NOTIFY_SPEED;
  439. ncm_do_notify(ncm);
  440. }
  441. static void ncm_notify_complete(struct usb_ep *ep, struct usb_request *req)
  442. {
  443. struct f_ncm *ncm = req->context;
  444. //struct usb_composite_dev *cdev = ncm->port.func.config->cdev;
  445. struct usb_cdc_notification *event = req->buf;
  446. spin_lock(&ncm->lock);
  447. switch (req->status) {
  448. case 0:
  449. TRACE_INFO("Notification %02x sent\r\n",
  450. event->bNotificationType);
  451. break;
  452. case -ECONNRESET:
  453. case -ESHUTDOWN:
  454. ncm->notify_state = NCM_NOTIFY_NONE;
  455. break;
  456. default:
  457. printf("event %02x --> %d\r\n",
  458. event->bNotificationType, req->status);
  459. break;
  460. }
  461. ncm->notify_req = req;
  462. ncm_do_notify(ncm);
  463. spin_unlock(&ncm->lock);
  464. }
  465. static void ncm_ep0out_complete(struct usb_ep *ep, struct usb_request *req)
  466. {
  467. /* now for SET_NTB_INPUT_SIZE only */
  468. unsigned in_size;
  469. struct usb_function *f = req->context;
  470. struct f_ncm *ncm = func_to_ncm(f);
  471. struct usb_composite_dev *cdev = ep->driver_data;
  472. req->context = NULL;
  473. cdev = cdev;
  474. if (req->status || req->actual != req->length) {
  475. DBG(cdev, "Bad control-OUT transfer\n");
  476. goto invalid;
  477. }
  478. in_size = get_unaligned_le32(req->buf);
  479. if (in_size < USB_CDC_NCM_NTB_MIN_IN_SIZE ||
  480. in_size > le32_to_cpu(ntb_parameters.dwNtbInMaxSize)) {
  481. DBG(cdev, "Got wrong INPUT SIZE (%d) from host\n", in_size);
  482. goto invalid;
  483. }
  484. ncm->port.fixed_in_len = in_size;
  485. VDBG(cdev, "Set NTB INPUT SIZE %d\n", in_size);
  486. return;
  487. invalid:
  488. usb_ep_set_halt(ep);
  489. return;
  490. }
  491. static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
  492. {
  493. struct f_ncm *ncm = func_to_ncm(f);
  494. struct usb_composite_dev *cdev = f->config->cdev;
  495. struct usb_request *req = cdev->req;
  496. int value = -EOPNOTSUPP;
  497. u16 w_index = le16_to_cpu(ctrl->wIndex);
  498. u16 w_value = le16_to_cpu(ctrl->wValue);
  499. u16 w_length = le16_to_cpu(ctrl->wLength);
  500. /*
  501. * composite driver infrastructure handles everything except
  502. * CDC class messages; interface activation uses set_alt().
  503. */
  504. switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
  505. case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  506. | USB_CDC_SET_ETHERNET_PACKET_FILTER:
  507. /*
  508. * see 6.2.30: no data, wIndex = interface,
  509. * wValue = packet filter bitmap
  510. */
  511. if (w_length != 0 || w_index != ncm->ctrl_id)
  512. goto invalid;
  513. DBG(cdev, "packet filter %02x\n", w_value);
  514. /*
  515. * REVISIT locking of cdc_filter. This assumes the UDC
  516. * driver won't have a concurrent packet TX irq running on
  517. * another CPU; or that if it does, this write is atomic...
  518. */
  519. ncm->port.cdc_filter = w_value;
  520. value = 0;
  521. break;
  522. /*
  523. * and optionally:
  524. * case USB_CDC_SEND_ENCAPSULATED_COMMAND:
  525. * case USB_CDC_GET_ENCAPSULATED_RESPONSE:
  526. * case USB_CDC_SET_ETHERNET_MULTICAST_FILTERS:
  527. * case USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER:
  528. * case USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER:
  529. * case USB_CDC_GET_ETHERNET_STATISTIC:
  530. */
  531. case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  532. | USB_CDC_GET_NTB_PARAMETERS:
  533. if (w_length == 0 || w_value != 0 || w_index != ncm->ctrl_id)
  534. goto invalid;
  535. value = w_length > sizeof ntb_parameters ?
  536. sizeof ntb_parameters : w_length;
  537. memcpy(req->buf, &ntb_parameters, value);
  538. VDBG(cdev, "Host asked NTB parameters\n");
  539. break;
  540. case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  541. | USB_CDC_GET_NTB_INPUT_SIZE:
  542. if (w_length < 4 || w_value != 0 || w_index != ncm->ctrl_id)
  543. goto invalid;
  544. put_unaligned_le32(ncm->port.fixed_in_len, req->buf);
  545. value = 4;
  546. VDBG(cdev, "Host asked INPUT SIZE, sending %d\n",
  547. ncm->fixed_in_len);
  548. break;
  549. case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  550. | USB_CDC_SET_NTB_INPUT_SIZE:
  551. {
  552. if (w_length != 4 || w_value != 0 || w_index != ncm->ctrl_id)
  553. goto invalid;
  554. req->complete = ncm_ep0out_complete;
  555. req->length = w_length;
  556. req->context = f;
  557. value = req->length;
  558. break;
  559. }
  560. case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  561. | USB_CDC_GET_NTB_FORMAT:
  562. {
  563. uint16_t format;
  564. if (w_length < 2 || w_value != 0 || w_index != ncm->ctrl_id)
  565. goto invalid;
  566. format = (ncm->parser_opts == &ndp16_opts) ? 0x0000 : 0x0001;
  567. put_unaligned_le16(format, req->buf);
  568. value = 2;
  569. VDBG(cdev, "Host asked NTB FORMAT, sending %d\n", format);
  570. break;
  571. }
  572. case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  573. | USB_CDC_SET_NTB_FORMAT:
  574. {
  575. if (w_length != 0 || w_index != ncm->ctrl_id)
  576. goto invalid;
  577. switch (w_value) {
  578. case 0x0000:
  579. ncm->parser_opts = &ndp16_opts;
  580. DBG(cdev, "NCM16 selected\n");
  581. break;
  582. case 0x0001:
  583. ncm->parser_opts = &ndp32_opts;
  584. DBG(cdev, "NCM32 selected\n");
  585. break;
  586. default:
  587. goto invalid;
  588. }
  589. value = 0;
  590. break;
  591. }
  592. case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  593. | USB_CDC_GET_CRC_MODE:
  594. {
  595. uint16_t is_crc;
  596. if (w_length < 2 || w_value != 0 || w_index != ncm->ctrl_id)
  597. goto invalid;
  598. is_crc = ncm->is_crc ? 0x0001 : 0x0000;
  599. put_unaligned_le16(is_crc, req->buf);
  600. value = 2;
  601. VDBG(cdev, "Host asked CRC MODE, sending %d\n", is_crc);
  602. break;
  603. }
  604. case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  605. | USB_CDC_SET_CRC_MODE:
  606. {
  607. int ndp_hdr_crc = 0;
  608. if (w_length != 0 || w_index != ncm->ctrl_id)
  609. goto invalid;
  610. switch (w_value) {
  611. case 0x0000:
  612. ncm->is_crc = false;
  613. ndp_hdr_crc = NCM_NDP_HDR_NOCRC;
  614. DBG(cdev, "non-CRC mode selected\n");
  615. break;
  616. case 0x0001:
  617. ncm->is_crc = true;
  618. ndp_hdr_crc = NCM_NDP_HDR_CRC;
  619. DBG(cdev, "CRC mode selected\n");
  620. break;
  621. default:
  622. goto invalid;
  623. }
  624. ncm->parser_opts->ndp_sign &= ~NCM_NDP_HDR_CRC_MASK;
  625. ncm->parser_opts->ndp_sign |= ndp_hdr_crc;
  626. value = 0;
  627. break;
  628. }
  629. /* and disabled in ncm descriptor: */
  630. /* case USB_CDC_GET_NET_ADDRESS: */
  631. /* case USB_CDC_SET_NET_ADDRESS: */
  632. case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | USB_CDC_GET_MAX_DATAGRAM_SIZE:
  633. if (w_length < 2 || w_value != 0)
  634. goto invalid;
  635. put_unaligned_le16(ETH_FRAME_LEN * 8, req->buf);
  636. value = 2;
  637. break;
  638. case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | USB_CDC_SET_MAX_DATAGRAM_SIZE:
  639. req->length = w_length;
  640. req->context = f;
  641. value = req->length;xTimerStartFromISR( ncm->timer, 0 );
  642. break;
  643. default:
  644. invalid:
  645. ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
  646. ctrl->bRequestType, ctrl->bRequest,
  647. w_value, w_index, w_length);
  648. }
  649. /* respond with data transfer or status phase? */
  650. if (value >= 0) {
  651. DBG(cdev, "ncm req%02x.%02x v%04x i%04x l%d\n",
  652. ctrl->bRequestType, ctrl->bRequest,
  653. w_value, w_index, w_length);
  654. req->zero = 0;
  655. req->length = value;
  656. value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
  657. if (value < 0)
  658. ERROR(cdev, "ncm req %02x.%02x response err %d\n",
  659. ctrl->bRequestType, ctrl->bRequest,
  660. value);
  661. }
  662. /* device either stalls (value < 0) or reports success */
  663. return value;
  664. }
  665. static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
  666. {
  667. struct f_ncm *ncm = func_to_ncm(f);
  668. struct usb_composite_dev *cdev = f->config->cdev;
  669. int ret = -1;
  670. /* Control interface has only altsetting 0 */
  671. if (intf == ncm->ctrl_id) {
  672. if (alt != 0)
  673. goto fail;
  674. if (ncm->notify->driver_data) {
  675. DBG(cdev, "reset ncm control %d\n", intf);
  676. usb_ep_disable(ncm->notify);
  677. }
  678. TRACE_INFO("ncm_set_alt notify\r\n");
  679. usb_ep_enable(ncm->notify, get_ep_desc(cdev->gadget, &fs_ncm_notify_desc, &hs_ncm_notify_desc));
  680. ncm->notify->driver_data = ncm;
  681. /* Data interface has two altsettings, 0 and 1 */
  682. } else if (intf == ncm->data_id) {
  683. if (alt > 1)
  684. goto fail;
  685. if (ncm->port.in_ep->driver_data) {
  686. ncm_reset_values(ncm);
  687. }
  688. if (alt == 1) {
  689. ncm->port.is_zlp_ok = true;
  690. ncm->port.cdc_filter = DEFAULT_FILTER;
  691. DBG(cdev, "activate ncm\n");
  692. printf("speed:%d\r\n", cdev->gadget->speed);
  693. if (cdev->gadget->speed == USB_SPEED_FULL) {
  694. ncm->port.in = get_ep_desc(cdev->gadget, &fs_ncm_in_desc, &hs_ncm_in_desc);
  695. ncm->port.out = get_ep_desc(cdev->gadget, &fs_ncm_out_desc, &hs_ncm_out_desc);
  696. }
  697. ret = gether_connect(&ncm->port);
  698. if (ret)
  699. return ret;
  700. }
  701. xTimerStopFromISR( ncm->timer, 0 );
  702. //spin_lock(&ncm->lock);
  703. //ncm_notify(ncm);
  704. //spin_unlock(&ncm->lock);
  705. } else
  706. goto fail;
  707. ncm->connect = true;
  708. return 0;
  709. fail:
  710. return -EINVAL;
  711. }
  712. /*
  713. * Because the data interface supports multiple altsettings,
  714. * this NCM function *MUST* implement a get_alt() method.
  715. */
  716. static int ncm_get_alt(struct usb_function *f, unsigned intf)
  717. {
  718. struct f_ncm *ncm = func_to_ncm(f);
  719. if (intf == ncm->ctrl_id)
  720. return 0;
  721. return ncm->port.in_ep->driver_data ? 1 : 0;
  722. }
  723. NetworkBufferDescriptor_t * pxResizeNetworkBufferWithDescriptorNoPadding( NetworkBufferDescriptor_t * pxNetworkBuffer,
  724. size_t xNewSizeBytes, int offset )
  725. {
  726. size_t xOriginalLength;
  727. uint8_t * pucBuffer;
  728. xOriginalLength = pxNetworkBuffer->xDataLength;
  729. pucBuffer = pvPortMalloc( xNewSizeBytes );
  730. if( pucBuffer == NULL )
  731. {
  732. /* In case the allocation fails, return NULL. */
  733. pxNetworkBuffer = NULL;
  734. }
  735. else
  736. {
  737. pxNetworkBuffer->xDataLength = xNewSizeBytes;
  738. ( void ) memcpy( pucBuffer + offset, pxNetworkBuffer->pucEthernetBuffer, xOriginalLength );
  739. vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
  740. pxNetworkBuffer->pucEthernetBuffer = pucBuffer;
  741. }
  742. return pxNetworkBuffer;
  743. }
  744. static NetworkBufferDescriptor_t *ncm_wrap_ntb(struct gether *port, NetworkBufferDescriptor_t* pxBufferDescriptor)
  745. {
  746. struct f_ncm *ncm = func_to_ncm(&port->func);
  747. NetworkBufferDescriptor_t *pxBufferDescriptor2;
  748. int ncb_len = 0;
  749. __le16 *tmp;
  750. int div = ntb_parameters.wNdpInDivisor;
  751. int rem = ntb_parameters.wNdpInPayloadRemainder;
  752. int pad = 0;
  753. int ndp_align = ntb_parameters.wNdpInAlignment;
  754. int ndp_pad = 0;
  755. unsigned max_size = ncm->port.fixed_in_len;
  756. struct ndp_parser_opts *opts = ncm->parser_opts;
  757. unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0;
  758. int net_data_len = pxBufferDescriptor->xDataLength;
  759. ncb_len += opts->nth_size;
  760. ndp_pad = ALIGN(ncb_len, ndp_align) - ncb_len;
  761. ncb_len += ndp_pad;
  762. ncb_len += opts->ndp_size;
  763. ncb_len += opts->dgram_item_len << 2; /* Datagram entry */
  764. ncb_len += opts->dgram_item_len << 2; /* Zero datagram entry */
  765. pad = ALIGN(ncb_len, div) + rem - ncb_len;
  766. ncb_len += pad;
  767. if (ncb_len + pxBufferDescriptor->xDataLength + crc_len > max_size) {
  768. printf("invalid ncm len\r\n");
  769. vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor);
  770. return NULL;
  771. }
  772. //pxBufferDescriptor2 = pxGetNetworkBufferWithDescriptor(ncb_len + pxBufferDescriptor->xDataLength + crc_len, 0);
  773. pxBufferDescriptor2 = pxResizeNetworkBufferWithDescriptorNoPadding(pxBufferDescriptor, ncb_len + net_data_len + crc_len, ncb_len);
  774. if (!pxBufferDescriptor2) {
  775. printf("resize ncm buf failed\r\n");
  776. vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor);
  777. return NULL;
  778. }
  779. //memcpy(pxBufferDescriptor2->pucEthernetBuffer + ncb_len, pxBufferDescriptor->pucEthernetBuffer, pxBufferDescriptor->xDataLength);
  780. //vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor);
  781. pxBufferDescriptor = pxBufferDescriptor2;
  782. tmp = (__le16 *)pxBufferDescriptor->pucEthernetBuffer;
  783. memset(tmp, 0, ncb_len);
  784. put_unaligned_le32(opts->nth_sign, tmp); /* dwSignature */
  785. tmp += 2;
  786. /* wHeaderLength */
  787. put_unaligned_le16(opts->nth_size, tmp++);
  788. tmp++; /* skip wSequence */
  789. put_ncm(&tmp, opts->block_length, ncb_len + net_data_len + crc_len); /* (d)wBlockLength */
  790. /* (d)wFpIndex */
  791. /* the first pointer is right after the NTH + align */
  792. put_ncm(&tmp, opts->fp_index, opts->nth_size + ndp_pad);
  793. tmp = tmp + ndp_pad;
  794. /* NDP */
  795. put_unaligned_le32(opts->ndp_sign, tmp); /* dwSignature */
  796. tmp += 2;
  797. /* wLength */
  798. put_unaligned_le16(ncb_len - opts->nth_size - pad, tmp++);
  799. tmp += opts->reserved1;
  800. tmp += opts->next_fp_index; /* skip reserved (d)wNextFpIndex */
  801. tmp += opts->reserved2;
  802. if (ncm->is_crc) {
  803. uint32_t crc;
  804. crc = xcrc32(pxBufferDescriptor->pucEthernetBuffer + ncb_len, net_data_len, ~0, HARD_CALC_CRC);
  805. put_unaligned_le32(crc, pxBufferDescriptor->pucEthernetBuffer + net_data_len + ncb_len);
  806. }
  807. /* (d)wDatagramIndex[0] */
  808. put_ncm(&tmp, opts->dgram_item_len, ncb_len);
  809. /* (d)wDatagramLength[0] */
  810. put_ncm(&tmp, opts->dgram_item_len, pxBufferDescriptor->xDataLength - ncb_len);
  811. /* (d)wDatagramIndex[1] and (d)wDatagramLength[1] already zeroed */
  812. return pxBufferDescriptor;
  813. }
  814. static void *ncm_wrap_ext_ntb(struct gether *port, void* bufferDescHandle)
  815. {
  816. struct f_ncm *ncm = func_to_ncm(&port->func);
  817. int ncb_len = 0;
  818. __le16 *tmp;
  819. int div = ntb_parameters.wNdpInDivisor;
  820. int rem = ntb_parameters.wNdpInPayloadRemainder;
  821. int pad = 0;
  822. int ndp_align = ntb_parameters.wNdpInAlignment;
  823. int ndp_pad = 0;
  824. unsigned max_size = ncm->port.fixed_in_len;
  825. struct ndp_parser_opts *opts = ncm->parser_opts;
  826. unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0;
  827. int net_data_len = 0;
  828. #if !USE_LWIP
  829. NetworkBufferDescriptor_t* pxBufferDescriptor = (NetworkBufferDescriptor_t*)bufferDescHandle;
  830. NetworkBufferDescriptor_t *pxBufferDescriptor2;
  831. #else
  832. struct pbuf *pxBufferDescriptor = (struct pbuf *)bufferDescHandle;
  833. struct pbuf *pxBufferDescriptor2;
  834. #endif
  835. ncb_len += opts->nth_size;
  836. ndp_pad = ALIGN(ncb_len, ndp_align) - ncb_len;
  837. ncb_len += ndp_pad;
  838. ncb_len += opts->ndp_size;
  839. ncb_len += opts->dgram_item_len << 2; /* Datagram entry */
  840. ncb_len += opts->dgram_item_len << 2; /* Zero datagram entry */
  841. pad = ALIGN(ncb_len, div) + rem - ncb_len;
  842. ncb_len += pad;
  843. #if !USE_LWIP
  844. net_data_len = pxBufferDescriptor->xDataLength;
  845. if (ncb_len + pxBufferDescriptor->xDataLength + crc_len > max_size) {
  846. printf("invalid ncm len\r\n");
  847. vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor);
  848. return NULL;
  849. }
  850. //pxBufferDescriptor2 = pxGetNetworkBufferWithDescriptor(ncb_len + pxBufferDescriptor->xDataLength + crc_len, 0);
  851. pxBufferDescriptor2 = pxResizeNetworkBufferWithDescriptorNoPadding(pxBufferDescriptor, ncb_len + net_data_len + crc_len, ncb_len);
  852. if (!pxBufferDescriptor2) {
  853. printf("resize ncm buf failed\r\n");
  854. vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor);
  855. return NULL;
  856. }
  857. //memcpy(pxBufferDescriptor2->pucEthernetBuffer + ncb_len, pxBufferDescriptor->pucEthernetBuffer, pxBufferDescriptor->xDataLength);
  858. //vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor);
  859. pxBufferDescriptor = pxBufferDescriptor2;
  860. tmp = (__le16 *)pxBufferDescriptor->pucEthernetBuffer;
  861. #else
  862. int new_ncm_len;
  863. net_data_len = pxBufferDescriptor->len;
  864. if (ncb_len + net_data_len + crc_len > max_size) {
  865. printf("invalid ncm len\r\n");
  866. pbuf_free(pxBufferDescriptor);
  867. return NULL;
  868. }
  869. new_ncm_len = ncb_len + net_data_len + crc_len;
  870. pxBufferDescriptor2 = pbuf_alloc(PBUF_RAW, new_ncm_len, PBUF_RAM);
  871. if (!pxBufferDescriptor2) {
  872. printf("resize ncm buf failed\r\n");
  873. pbuf_free(pxBufferDescriptor);
  874. return NULL;
  875. }
  876. memcpy((void*)((char *)pxBufferDescriptor2->payload + ncb_len), pxBufferDescriptor->payload, pxBufferDescriptor->len);
  877. pbuf_free(pxBufferDescriptor);
  878. pxBufferDescriptor = pxBufferDescriptor2;
  879. tmp = (__le16 *)pxBufferDescriptor->payload;
  880. #endif
  881. memset(tmp, 0, ncb_len);
  882. put_unaligned_le32(opts->nth_sign, tmp); /* dwSignature */
  883. tmp += 2;
  884. /* wHeaderLength */
  885. put_unaligned_le16(opts->nth_size, tmp++);
  886. tmp++; /* skip wSequence */
  887. put_ncm(&tmp, opts->block_length, ncb_len + net_data_len + crc_len); /* (d)wBlockLength */
  888. /* (d)wFpIndex */
  889. /* the first pointer is right after the NTH + align */
  890. put_ncm(&tmp, opts->fp_index, opts->nth_size + ndp_pad);
  891. tmp = tmp + ndp_pad;
  892. /* NDP */
  893. put_unaligned_le32(opts->ndp_sign, tmp); /* dwSignature */
  894. tmp += 2;
  895. /* wLength */
  896. put_unaligned_le16(ncb_len - opts->nth_size - pad, tmp++);
  897. tmp += opts->reserved1;
  898. tmp += opts->next_fp_index; /* skip reserved (d)wNextFpIndex */
  899. tmp += opts->reserved2;
  900. #if !USE_LWIP
  901. if (ncm->is_crc) {
  902. uint32_t crc;
  903. crc = xcrc32(pxBufferDescriptor->pucEthernetBuffer + ncb_len, net_data_len, ~0, HARD_CALC_CRC);
  904. put_unaligned_le32(crc, pxBufferDescriptor->pucEthernetBuffer + net_data_len + ncb_len);
  905. }
  906. /* (d)wDatagramIndex[0] */
  907. put_ncm(&tmp, opts->dgram_item_len, ncb_len);
  908. /* (d)wDatagramLength[0] */
  909. put_ncm(&tmp, opts->dgram_item_len, pxBufferDescriptor->xDataLength - ncb_len);
  910. /* (d)wDatagramIndex[1] and (d)wDatagramLength[1] already zeroed */
  911. #else
  912. if (ncm->is_crc) {
  913. uint32_t crc;
  914. crc = xcrc32((unsigned char *)pxBufferDescriptor->payload + ncb_len, net_data_len, ~0, HARD_CALC_CRC);
  915. put_unaligned_le32(crc, (void*)((char *)pxBufferDescriptor->payload + net_data_len + ncb_len));
  916. }
  917. /* (d)wDatagramIndex[0] */
  918. put_ncm(&tmp, opts->dgram_item_len, ncb_len);
  919. /* (d)wDatagramLength[0] */
  920. put_ncm(&tmp, opts->dgram_item_len, pxBufferDescriptor->len - ncb_len);
  921. /* (d)wDatagramIndex[1] and (d)wDatagramLength[1] already zeroed */
  922. #endif
  923. return (void*)pxBufferDescriptor;
  924. }
  925. static int ncm_unwrap_ntb(struct gether *port, uint8_t* data_buf, int len, List_t *frames)
  926. {
  927. struct f_ncm *ncm = func_to_ncm(&port->func);
  928. __le16 *tmp = (void *) data_buf;
  929. unsigned index, index2;
  930. int ndp_index;
  931. unsigned dg_len, dg_len2;
  932. unsigned ndp_len;
  933. #if !USE_LWIP
  934. NetworkBufferDescriptor_t* pxBufferDescriptor;
  935. #else
  936. struct pbuf *pxBufferDescriptor;
  937. struct pbuf *iter = NULL;
  938. struct pbuf *first_node = NULL;
  939. #endif
  940. int ret = -EINVAL;
  941. unsigned max_size = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize);
  942. struct ndp_parser_opts *opts = ncm->parser_opts;
  943. unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0;
  944. int dgram_counter;
  945. /* dwSignature */
  946. if (get_unaligned_le32(tmp) != opts->nth_sign) {
  947. INFO(port->func.config->cdev, "Wrong NTH SIGN, skblen %d\n", len);
  948. goto err;
  949. }
  950. tmp += 2;
  951. /* wHeaderLength */
  952. if (get_unaligned_le16(tmp++) != opts->nth_size) {
  953. INFO(port->func.config->cdev, "Wrong NTB headersize\n");
  954. goto err;
  955. }
  956. tmp++; /* skip wSequence */
  957. /* (d)wBlockLength */
  958. if (get_ncm(&tmp, opts->block_length) > max_size) {
  959. INFO(port->func.config->cdev, "OUT size exceeded\n");
  960. goto err;
  961. }
  962. ndp_index = get_ncm(&tmp, opts->fp_index);
  963. /* Run through all the NDP's in the NTB */
  964. do {
  965. /* NCM 3.2 */
  966. if (((ndp_index % 4) != 0) && (ndp_index < opts->nth_size)) {
  967. INFO(port->func.config->cdev, "Bad index: %#X\n",
  968. ndp_index);
  969. goto err;
  970. }
  971. /* walk through NDP */
  972. tmp = (void *)(data_buf + ndp_index);
  973. if (get_unaligned_le32(tmp) != opts->ndp_sign) {
  974. INFO(port->func.config->cdev, "Wrong NDP SIGN\n");
  975. goto err;
  976. }
  977. tmp += 2;
  978. ndp_len = get_unaligned_le16(tmp++);
  979. /*
  980. * NCM 3.3.1
  981. * entry is 2 items
  982. * item size is 16/32 bits, opts->dgram_item_len * 2 bytes
  983. * minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry
  984. * Each entry is a dgram index and a dgram length.
  985. */
  986. if ((ndp_len < opts->ndp_size + 2 * 2 * (opts->dgram_item_len * 2))
  987. || (ndp_len % opts->ndplen_align != 0)) {
  988. INFO(port->func.config->cdev, "Bad NDP length: %#X\n", ndp_len);
  989. goto err;
  990. }
  991. tmp += opts->reserved1;
  992. /* Check for another NDP (d)wNextNdpIndex */
  993. ndp_index = get_ncm(&tmp, opts->next_fp_index);
  994. tmp += opts->reserved2;
  995. ndp_len -= opts->ndp_size;
  996. index2 = get_ncm(&tmp, opts->dgram_item_len);
  997. dg_len2 = get_ncm(&tmp, opts->dgram_item_len);
  998. dgram_counter = 0;
  999. do {
  1000. index = index2;
  1001. dg_len = dg_len2;
  1002. //printf("ncm payload len:%d\r\n", dg_len);
  1003. if (dg_len < 14 + crc_len) { /* ethernet header + crc */
  1004. INFO(port->func.config->cdev, "Bad dgram length: %x\n",
  1005. dg_len);
  1006. goto err;
  1007. }
  1008. if (ncm->is_crc) {
  1009. uint32_t crc, crc2;
  1010. crc = get_unaligned_le32(data_buf +
  1011. index + dg_len - crc_len);
  1012. crc2 = xcrc32(data_buf + index,
  1013. dg_len - crc_len, ~0, HARD_CALC_CRC);
  1014. if (crc != crc2) {
  1015. INFO(port->func.config->cdev, "Bad CRC\n");
  1016. goto err;
  1017. }
  1018. }
  1019. index2 = get_ncm(&tmp, opts->dgram_item_len);
  1020. dg_len2 = get_ncm(&tmp, opts->dgram_item_len);
  1021. #if !USE_LWIP
  1022. pxBufferDescriptor = pxGetNetworkBufferWithDescriptor(dg_len - crc_len, 0);
  1023. if (!pxBufferDescriptor) {
  1024. goto err;
  1025. }
  1026. memcpy(pxBufferDescriptor->pucEthernetBuffer, data_buf + index, dg_len - crc_len);
  1027. if (pxBufferDescriptor->xDataLength > (dg_len - crc_len)) {
  1028. memset(pxBufferDescriptor->pucEthernetBuffer + dg_len - crc_len, 0, pxBufferDescriptor->xDataLength - (dg_len - crc_len));
  1029. }
  1030. listSET_LIST_ITEM_OWNER(&pxBufferDescriptor->xBufferListItem, pxBufferDescriptor);
  1031. vListInsertEnd(frames, &pxBufferDescriptor->xBufferListItem);
  1032. #else
  1033. pxBufferDescriptor = pbuf_alloc(PBUF_RAW, dg_len - crc_len, PBUF_RAM);
  1034. if (!pxBufferDescriptor) {
  1035. goto err;
  1036. }
  1037. memcpy(pxBufferDescriptor->payload, data_buf + index, dg_len - crc_len);
  1038. if (pxBufferDescriptor->len > (dg_len - crc_len)) {
  1039. memset((void*)((char *)pxBufferDescriptor->payload + dg_len - crc_len), 0, pxBufferDescriptor->len - (dg_len - crc_len));
  1040. }
  1041. if (first_node == NULL) {
  1042. struct pbuf* header = (struct pbuf*)frames;
  1043. first_node = pxBufferDescriptor;
  1044. iter = pxBufferDescriptor;
  1045. iter->next = NULL;
  1046. header->next = first_node;
  1047. } else {
  1048. iter->next = pxBufferDescriptor;
  1049. iter = pxBufferDescriptor;
  1050. iter->next = NULL;
  1051. }
  1052. #endif
  1053. ndp_len -= ((opts->dgram_item_len << 1) << 1);
  1054. dgram_counter++;
  1055. if (index2 == 0 || dg_len2 == 0)
  1056. break;
  1057. } while (ndp_len > (opts->dgram_item_len << 1) << 1); /* zero entry */
  1058. }while (ndp_index);
  1059. VDBG(port->func.config->cdev,
  1060. "Parsed NTB with %d frames\n", dgram_counter);
  1061. return 0;
  1062. err:
  1063. return ret;
  1064. }
  1065. static void ncm_suspend(struct usb_function *f)
  1066. {
  1067. struct f_ncm *ncm = func_to_ncm(f);
  1068. //struct usb_composite_dev *cdev = f->config->cdev;
  1069. printf("%s:%d\n", __func__, __LINE__);
  1070. }
  1071. static void ncm_disable(struct usb_function *f)
  1072. {
  1073. struct f_ncm *ncm = func_to_ncm(f);
  1074. //struct usb_composite_dev *cdev = f->config->cdev;
  1075. DBG(cdev, "ncm deactivated\n");
  1076. spin_lock(&ncm->lock);
  1077. if (!ncm->connect) {
  1078. spin_unlock(&ncm->lock);
  1079. return;
  1080. }
  1081. TRACE_INFO("usb disconnect\r\n");
  1082. if (ncm->notify->driver_data) {
  1083. usb_ep_disable(ncm->notify);
  1084. ncm->notify->driver_data = NULL;
  1085. ncm->notify->desc = NULL;
  1086. }
  1087. gether_disconnect(&ncm->port);
  1088. ncm->connect = false;
  1089. spin_unlock(&ncm->lock);
  1090. }
  1091. /*static void ncm_disconnect(struct gether *port)
  1092. {
  1093. struct f_ncm *ncm = func_to_ncm(&port->func);
  1094. spin_lock(&ncm->lock);
  1095. if (ncm->notify->driver_data) {
  1096. usb_ep_disable(ncm->notify);
  1097. ncm->notify->driver_data = NULL;
  1098. ncm->notify->desc = NULL;
  1099. }
  1100. spin_unlock(&ncm->lock);
  1101. }*/
  1102. static void ncm_open(struct gether *geth)
  1103. {
  1104. struct f_ncm *ncm = func_to_ncm(&geth->func);
  1105. DBG(ncm->port.func.config->cdev, "%s\n", __func__);
  1106. spin_lock(&ncm->lock);
  1107. ncm->is_open = true;
  1108. ncm_notify(ncm);
  1109. spin_unlock(&ncm->lock);
  1110. }
  1111. static void ncm_close(struct gether *geth)
  1112. {
  1113. struct f_ncm *ncm = func_to_ncm(&geth->func);
  1114. DBG(ncm->port.func.config->cdev, "%s\n", __func__);
  1115. spin_lock(&ncm->lock);
  1116. ncm->is_open = false;
  1117. ncm_notify(ncm);
  1118. spin_unlock(&ncm->lock);
  1119. }
  1120. /*-------------------------------------------------------------------------*/
  1121. /* ethernet function driver setup/binding */
  1122. static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
  1123. {
  1124. struct usb_composite_dev *cdev = c->cdev;
  1125. struct f_ncm *ncm = func_to_ncm(f);
  1126. int status;
  1127. struct usb_ep *ep;
  1128. /* allocate instance-specific interface IDs */
  1129. status = usb_interface_id(c, f);
  1130. if (status < 0)
  1131. goto fail;
  1132. ncm->ctrl_id = status;
  1133. ncm_iad_desc.bFirstInterface = status;
  1134. ncm_control_intf.bInterfaceNumber = status;
  1135. ncm_union_desc.bMasterInterface0 = status;
  1136. status = usb_interface_id(c, f);
  1137. if (status < 0)
  1138. goto fail;
  1139. ncm->data_id = status;
  1140. ncm_data_nop_intf.bInterfaceNumber = status;
  1141. ncm_data_intf.bInterfaceNumber = status;
  1142. ncm_union_desc.bSlaveInterface0 = status;
  1143. status = -ENODEV;
  1144. ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_in_desc);
  1145. if (!ep)
  1146. goto fail;
  1147. ncm->port.in_ep = ep;
  1148. ep->driver_data = cdev; /* claim */
  1149. ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc);
  1150. if (!ep)
  1151. goto fail;
  1152. ncm->port.out_ep = ep;
  1153. ep->driver_data = cdev; /* claim */
  1154. /* allocate instance-specific endpoints */
  1155. ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc);
  1156. if (!ep)
  1157. goto fail;
  1158. ncm->notify = ep;
  1159. ep->driver_data = cdev; /* claim */
  1160. /* allocate notification request and buffer */
  1161. ncm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL);
  1162. if (!ncm->notify_req)
  1163. goto fail;
  1164. ncm->notify_req->buf = kmalloc(NCM_STATUS_BYTECOUNT, GFP_KERNEL);
  1165. if (!ncm->notify_req->buf)
  1166. goto fail;
  1167. ncm->notify_req->context = ncm;
  1168. ncm->notify_req->complete = ncm_notify_complete;
  1169. status = -ENOMEM;
  1170. /* copy descriptors, and track endpoint copies */
  1171. f->descriptors = usb_copy_descriptors(ncm_fs_function);
  1172. if (!f->descriptors)
  1173. goto fail;
  1174. /*
  1175. * support all relevant hardware speeds... we expect that when
  1176. * hardware is dual speed, all bulk-capable endpoints work at
  1177. * both speeds
  1178. */
  1179. if (gadget_is_dualspeed(c->cdev->gadget)) {
  1180. hs_ncm_in_desc.bEndpointAddress =
  1181. fs_ncm_in_desc.bEndpointAddress;
  1182. hs_ncm_out_desc.bEndpointAddress =
  1183. fs_ncm_out_desc.bEndpointAddress;
  1184. hs_ncm_notify_desc.bEndpointAddress =
  1185. fs_ncm_notify_desc.bEndpointAddress;
  1186. /* copy descriptors, and track endpoint copies */
  1187. f->hs_descriptors = usb_copy_descriptors(ncm_hs_function);
  1188. if (!f->hs_descriptors)
  1189. goto fail;
  1190. }
  1191. DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n",
  1192. gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
  1193. ncm->in_ep->name, ncm->out_ep->name,
  1194. ncm->notify->name);
  1195. return 0;
  1196. fail:
  1197. if (f->descriptors)
  1198. usb_free_descriptors(f->descriptors);
  1199. if (ncm->notify_req) {
  1200. kfree(ncm->notify_req->buf);
  1201. usb_ep_free_request(ncm->notify, ncm->notify_req);
  1202. }
  1203. /* we might as well release our claims on endpoints */
  1204. if (ncm->notify)
  1205. ncm->notify->driver_data = NULL;
  1206. if (ncm->port.out_ep->desc)
  1207. ncm->port.out_ep->driver_data = NULL;
  1208. if (ncm->port.in_ep->desc)
  1209. ncm->port.in_ep->driver_data = NULL;
  1210. printf("%s: can't bind, err %d\r\n", f->name, status);
  1211. return status;
  1212. }
  1213. static void
  1214. ncm_unbind(struct usb_configuration *c, struct usb_function *f)
  1215. {
  1216. struct f_ncm *ncm = func_to_ncm(f);
  1217. DBG(c->cdev, "ncm unbind\n");
  1218. if (gadget_is_dualspeed(c->cdev->gadget))
  1219. usb_free_descriptors(f->hs_descriptors);
  1220. usb_free_descriptors(f->descriptors);
  1221. kfree(ncm->notify_req->buf);
  1222. usb_ep_free_request(ncm->notify, ncm->notify_req);
  1223. ncm_string_defs[1].s = NULL;
  1224. kfree(ncm);
  1225. }
  1226. static void prvNcmTimerCallback( TimerHandle_t xTimerHandle )
  1227. {
  1228. struct f_ncm *ncm = (struct f_ncm *)pvTimerGetTimerID(xTimerHandle);
  1229. TRACE_INFO("prvNcmTimerCallback\r\n");
  1230. ncm->is_open = true;
  1231. ncm_notify(ncm);
  1232. }
  1233. /**
  1234. * ncm_bind_config - add CDC Network link to a configuration
  1235. * @c: the configuration to support the network link
  1236. * @ethaddr: a buffer in which the ethernet address of the host side
  1237. * side of the link was recorded
  1238. * Context: single threaded during gadget setup
  1239. *
  1240. * Returns zero on success, else negative errno.
  1241. *
  1242. * Caller must have called @gether_setup(). Caller is also responsible
  1243. * for calling @gether_cleanup() before module unload.
  1244. */
  1245. int ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
  1246. {
  1247. struct f_ncm *ncm;
  1248. int status;
  1249. /* maybe allocate device-global string IDs */
  1250. if (ncm_string_defs[0].id == 0) {
  1251. /* control interface label */
  1252. status = usb_string_id(c->cdev);
  1253. if (status < 0)
  1254. return status;
  1255. ncm_string_defs[STRING_CTRL_IDX].id = status;
  1256. ncm_control_intf.iInterface = status;
  1257. /* data interface label */
  1258. status = usb_string_id(c->cdev);
  1259. if (status < 0)
  1260. return status;
  1261. ncm_string_defs[STRING_DATA_IDX].id = status;
  1262. ncm_data_nop_intf.iInterface = status;
  1263. ncm_data_intf.iInterface = status;
  1264. /* MAC address */
  1265. status = usb_string_id(c->cdev);
  1266. if (status < 0)
  1267. return status;
  1268. ncm_string_defs[STRING_MAC_IDX].id = status;
  1269. ecm_desc.iMACAddress = status;
  1270. /* IAD */
  1271. status = usb_string_id(c->cdev);
  1272. if (status < 0)
  1273. return status;
  1274. ncm_string_defs[STRING_IAD_IDX].id = status;
  1275. ncm_iad_desc.iFunction = status;
  1276. }
  1277. /* allocate and initialize one new instance */
  1278. ncm = kzalloc(sizeof *ncm, GFP_KERNEL);
  1279. if (!ncm)
  1280. return -ENOMEM;
  1281. /* export host's Ethernet address in CDC format */
  1282. snprintf(ncm->ethaddr, sizeof ncm->ethaddr,
  1283. "%02X%02X%02X%02X%02X%02X",
  1284. ethaddr[0], ethaddr[1], ethaddr[2],
  1285. ethaddr[3], ethaddr[4], ethaddr[5]);
  1286. ncm_string_defs[STRING_MAC_IDX].s = ncm->ethaddr;
  1287. spin_lock_init(&ncm->lock);
  1288. ncm_reset_values(ncm);
  1289. ncm->port.is_fixed = true;
  1290. listSET_LIST_ITEM_OWNER(&(ncm->port.func.list), &(ncm->port.func));
  1291. ncm->port.func.powner = (void*)ncm;
  1292. ncm->port.func.name = "cdc_network";
  1293. ncm->port.func.strings = ncm_strings;
  1294. /* descriptors are per-instance copies */
  1295. ncm->port.func.bind = ncm_bind;
  1296. ncm->port.func.unbind = ncm_unbind;
  1297. ncm->port.func.set_alt = ncm_set_alt;
  1298. ncm->port.func.get_alt = ncm_get_alt;
  1299. ncm->port.func.setup = ncm_setup;
  1300. ncm->port.func.disable = ncm_disable;
  1301. ncm->port.func.suspend = ncm_suspend;
  1302. ncm->port.unwrap = ncm_unwrap_ntb;
  1303. ncm->port.wrap = ncm_wrap_ntb;
  1304. ncm->port.wrap_ext = ncm_wrap_ext_ntb;
  1305. ncm->port.disconnect_cb = NULL;//ncm_disconnect;
  1306. ncm->port.open = ncm_open;
  1307. ncm->port.close = ncm_close;
  1308. ncm->port.in = get_ep_desc(c->cdev->gadget, &hs_ncm_in_desc, &fs_ncm_in_desc);
  1309. ncm->port.out = get_ep_desc(c->cdev->gadget, &hs_ncm_out_desc, &fs_ncm_out_desc);
  1310. ncm->timer = xTimerCreate( "NcmTimer",
  1311. pdMS_TO_TICKS(3000), /* The period of the software timer in ticks. */
  1312. pdFALSE, /* xAutoReload is set to pdFALSE, so this is a one-shot timer. */
  1313. (void*)ncm, /* The timer's ID is not used. */
  1314. prvNcmTimerCallback );
  1315. status = usb_add_function(c, &ncm->port.func);
  1316. if (status) {
  1317. ncm_string_defs[1].s = NULL;
  1318. kfree(ncm);
  1319. }
  1320. return status;
  1321. }