rndis.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327
  1. /*
  2. * File : rndis.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006-2013, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2012-12-24 heyuanjie87 first version
  13. * 2013-04-13 aozima update ethernet driver.
  14. * 2013-04-26 aozima align the desc to 4byte.
  15. * 2013-05-08 aozima pad a dummy when send MAX_PKT_SIZE.
  16. * 2013-05-09 aozima add delay linkup feature.
  17. * 2013-07-09 aozima support respone chain list.
  18. * 2013-07-18 aozima re-initial respone chain list when RNDIS restart.
  19. * 2017-11-25 ZYH fix it and add OS descriptor
  20. */
  21. #include <rtdevice.h>
  22. #include "cdc.h"
  23. #include "rndis.h"
  24. #include "ndis.h"
  25. //#define RNDIS_DEBUG
  26. //#define RNDIS_DELAY_LINK_UP
  27. #ifdef RNDIS_DEBUG
  28. #define RNDIS_PRINTF rt_kprintf("[RNDIS] "); rt_kprintf
  29. #else
  30. #define RNDIS_PRINTF(...)
  31. #endif /* RNDIS_DEBUG */
  32. /* RT-Thread LWIP ethernet interface */
  33. #include <netif/ethernetif.h>
  34. struct rt_rndis_response
  35. {
  36. struct rt_list_node list;
  37. const void * buffer;
  38. };
  39. #define MAX_ADDR_LEN 6
  40. struct rt_rndis_eth
  41. {
  42. /* inherit from ethernet device */
  43. struct eth_device parent;
  44. struct ufunction *func;
  45. /* interface address info */
  46. rt_uint8_t host_addr[MAX_ADDR_LEN];
  47. rt_uint8_t dev_addr[MAX_ADDR_LEN];
  48. #ifdef RNDIS_DELAY_LINK_UP
  49. struct rt_timer timer;
  50. #endif /* RNDIS_DELAY_LINK_UP */
  51. ALIGN(4)
  52. rt_uint8_t rx_pool[512];
  53. ALIGN(4)
  54. rt_uint8_t tx_pool[512];
  55. rt_uint32_t cmd_pool[2];
  56. ALIGN(4)
  57. char rx_buffer[sizeof(struct rndis_packet_msg) + USB_ETH_MTU + 14];
  58. rt_size_t rx_offset;
  59. rt_size_t rx_length;
  60. rt_bool_t rx_flag;
  61. rt_bool_t rx_frist;
  62. ALIGN(4)
  63. char tx_buffer[sizeof(struct rndis_packet_msg) + USB_ETH_MTU + 14];
  64. struct rt_semaphore tx_buffer_free;
  65. struct rt_list_node response_list;
  66. rt_bool_t need_notify;
  67. struct cdc_eps eps;
  68. };
  69. typedef struct rt_rndis_eth * rt_rndis_eth_t;
  70. static rt_uint32_t oid_packet_filter = 0x0000000;
  71. ALIGN(4)
  72. static struct udevice_descriptor _dev_desc =
  73. {
  74. USB_DESC_LENGTH_DEVICE, /* bLength */
  75. USB_DESC_TYPE_DEVICE, /* type */
  76. USB_BCD_VERSION, /* bcdUSB */
  77. 0xEF, /* bDeviceClass */
  78. 0x04, /* bDeviceSubClass */
  79. 0x01, /* bDeviceProtocol */
  80. USB_CDC_BUFSIZE, /* bMaxPacketSize0 */
  81. _VENDOR_ID, /* idVendor */
  82. _PRODUCT_ID, /* idProduct */
  83. USB_BCD_DEVICE, /* bcdDevice */
  84. USB_STRING_MANU_INDEX, /* iManufacturer */
  85. USB_STRING_PRODUCT_INDEX, /* iProduct */
  86. USB_STRING_SERIAL_INDEX, /* iSerialNumber */
  87. USB_DYNAMIC /* bNumConfigurations */
  88. };
  89. /* communcation interface descriptor */
  90. ALIGN(4)
  91. const static struct ucdc_comm_descriptor _comm_desc =
  92. {
  93. #ifdef RT_USB_DEVICE_COMPOSITE
  94. /* Interface Association Descriptor */
  95. USB_DESC_LENGTH_IAD,
  96. USB_DESC_TYPE_IAD,
  97. USB_DYNAMIC,
  98. 0x02,
  99. USB_CDC_CLASS_COMM,
  100. USB_CDC_SUBCLASS_ACM,
  101. USB_CDC_PROTOCOL_VENDOR,
  102. 0x00,
  103. #endif
  104. /* Interface Descriptor */
  105. USB_DESC_LENGTH_INTERFACE,
  106. USB_DESC_TYPE_INTERFACE,
  107. USB_DYNAMIC,
  108. 0x00,
  109. 0x01,
  110. USB_CDC_CLASS_COMM,
  111. USB_CDC_SUBCLASS_ACM,
  112. USB_CDC_PROTOCOL_VENDOR,
  113. 0x00,
  114. /* Header Functional Descriptor */
  115. 0x05,
  116. USB_CDC_CS_INTERFACE,
  117. USB_CDC_SCS_HEADER,
  118. 0x0110,
  119. /* Call Management Functional Descriptor */
  120. 0x05,
  121. USB_CDC_CS_INTERFACE,
  122. USB_CDC_SCS_CALL_MGMT,
  123. 0x00,
  124. USB_DYNAMIC,
  125. /* Abstract Control Management Functional Descriptor */
  126. 0x04,
  127. USB_CDC_CS_INTERFACE,
  128. USB_CDC_SCS_ACM,
  129. 0x02,
  130. /* Union Functional Descriptor */
  131. 0x05,
  132. USB_CDC_CS_INTERFACE,
  133. USB_CDC_SCS_UNION,
  134. USB_DYNAMIC,
  135. USB_DYNAMIC,
  136. /* Endpoint Descriptor */
  137. USB_DESC_LENGTH_ENDPOINT,
  138. USB_DESC_TYPE_ENDPOINT,
  139. USB_DIR_IN | USB_DYNAMIC,
  140. USB_EP_ATTR_INT,
  141. 0x08,
  142. 0x0A,
  143. };
  144. /* data interface descriptor */
  145. ALIGN(4)
  146. const static struct ucdc_data_descriptor _data_desc =
  147. {
  148. /* interface descriptor */
  149. USB_DESC_LENGTH_INTERFACE,
  150. USB_DESC_TYPE_INTERFACE,
  151. USB_DYNAMIC,
  152. 0x00,
  153. 0x02,
  154. USB_CDC_CLASS_DATA,
  155. 0x00,
  156. 0x00,
  157. 0x00,
  158. /* endpoint, bulk out */
  159. USB_DESC_LENGTH_ENDPOINT,
  160. USB_DESC_TYPE_ENDPOINT,
  161. USB_DIR_OUT | USB_DYNAMIC,
  162. USB_EP_ATTR_BULK,
  163. USB_DYNAMIC,
  164. 0x00,
  165. /* endpoint, bulk in */
  166. USB_DESC_LENGTH_ENDPOINT,
  167. USB_DESC_TYPE_ENDPOINT,
  168. USB_DYNAMIC | USB_DIR_IN,
  169. USB_EP_ATTR_BULK,
  170. USB_DYNAMIC,
  171. 0x00,
  172. };
  173. ALIGN(4)
  174. const static char* _ustring[] =
  175. {
  176. "Language", /* LANGID */
  177. "RT-Thread Team.", /* MANU */
  178. "RT-Thread RNDIS device", /* PRODUCT */
  179. "1.1.0", /* SERIAL */
  180. "Configuration", /* CONFIG */
  181. "Interface", /* INTERFACE */
  182. USB_STRING_OS
  183. };
  184. struct usb_os_function_comp_id_descriptor rndis_func_comp_id_desc =
  185. {
  186. .bFirstInterfaceNumber = USB_DYNAMIC,
  187. .reserved1 = 0x01,
  188. .compatibleID = {'R', 'N', 'D', 'I', 'S', 0x00, 0x00, 0x00},
  189. .subCompatibleID = {'5', '1', '6', '2', '0', '0', '1', 0x00},
  190. .reserved2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
  191. };
  192. //FS and HS needed
  193. static struct usb_qualifier_descriptor dev_qualifier =
  194. {
  195. sizeof(dev_qualifier), //bLength
  196. USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType
  197. 0x0200, //bcdUSB
  198. USB_CLASS_CDC, //bDeviceClass
  199. USB_CDC_SUBCLASS_ACM, //bDeviceSubClass
  200. USB_CDC_PROTOCOL_VENDOR, //bDeviceProtocol
  201. 64, //bMaxPacketSize0
  202. 0x01, //bNumConfigurations
  203. 0,
  204. };
  205. /* supported OIDs */
  206. ALIGN(4)
  207. const static rt_uint32_t oid_supported_list[] =
  208. {
  209. /* General OIDs */
  210. OID_GEN_SUPPORTED_LIST,
  211. OID_GEN_HARDWARE_STATUS,
  212. OID_GEN_MEDIA_SUPPORTED,
  213. OID_GEN_MEDIA_IN_USE,
  214. OID_GEN_MAXIMUM_FRAME_SIZE,
  215. OID_GEN_LINK_SPEED,
  216. OID_GEN_TRANSMIT_BLOCK_SIZE,
  217. OID_GEN_RECEIVE_BLOCK_SIZE,
  218. OID_GEN_VENDOR_ID,
  219. OID_GEN_VENDOR_DESCRIPTION,
  220. OID_GEN_VENDOR_DRIVER_VERSION,
  221. OID_GEN_CURRENT_PACKET_FILTER,
  222. OID_GEN_MAXIMUM_TOTAL_SIZE,
  223. OID_GEN_MEDIA_CONNECT_STATUS,
  224. OID_GEN_PHYSICAL_MEDIUM,
  225. /* General Statistic OIDs */
  226. OID_GEN_XMIT_OK,
  227. OID_GEN_RCV_OK,
  228. OID_GEN_XMIT_ERROR,
  229. OID_GEN_RCV_ERROR,
  230. OID_GEN_RCV_NO_BUFFER,
  231. /* Please configure us */
  232. OID_GEN_RNDIS_CONFIG_PARAMETER,
  233. /* 802.3 OIDs */
  234. OID_802_3_PERMANENT_ADDRESS,
  235. OID_802_3_CURRENT_ADDRESS,
  236. OID_802_3_MULTICAST_LIST,
  237. OID_802_3_MAXIMUM_LIST_SIZE,
  238. /* 802.3 Statistic OIDs */
  239. OID_802_3_RCV_ERROR_ALIGNMENT,
  240. OID_802_3_XMIT_ONE_COLLISION,
  241. OID_802_3_XMIT_MORE_COLLISIONS,
  242. OID_802_3_MAC_OPTIONS,
  243. };
  244. static rt_uint8_t rndis_message_buffer[RNDIS_MESSAGE_BUFFER_SIZE];
  245. static void _rndis_response_available(ufunction_t func)
  246. {
  247. rt_rndis_eth_t device = (rt_rndis_eth_t)func->user_data;
  248. rt_uint32_t * data;
  249. if(device->need_notify == RT_TRUE)
  250. {
  251. device->need_notify = RT_FALSE;
  252. data = (rt_uint32_t *)device->eps.ep_cmd->buffer;
  253. data[0] = RESPONSE_AVAILABLE;
  254. data[1] = 0;
  255. device->eps.ep_cmd->request.buffer = device->eps.ep_cmd->buffer;
  256. device->eps.ep_cmd->request.size = 8;
  257. device->eps.ep_cmd->request.req_type = UIO_REQUEST_WRITE;
  258. rt_usbd_io_request(func->device, device->eps.ep_cmd, &device->eps.ep_cmd->request);
  259. }
  260. }
  261. static rt_err_t _rndis_init_response(ufunction_t func, rndis_init_msg_t msg)
  262. {
  263. rndis_init_cmplt_t resp;
  264. struct rt_rndis_response * response;
  265. response = rt_malloc(sizeof(struct rt_rndis_response));
  266. resp = rt_malloc(sizeof(struct rndis_init_cmplt));
  267. if( (response == RT_NULL) || (resp == RT_NULL) )
  268. {
  269. RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
  270. if(response != RT_NULL)
  271. rt_free(response);
  272. if(resp != RT_NULL)
  273. rt_free(resp);
  274. return -RT_ENOMEM;
  275. }
  276. resp->RequestId = msg->RequestId;
  277. resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
  278. resp->MessageLength = sizeof(struct rndis_init_cmplt);
  279. resp->MajorVersion = RNDIS_MAJOR_VERSION;
  280. resp->MinorVersion = RNDIS_MAJOR_VERSION;
  281. resp->Status = RNDIS_STATUS_SUCCESS;
  282. resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
  283. resp->Medium = RNDIS_MEDIUM_802_3;
  284. resp->MaxPacketsPerTransfer = 1;
  285. resp->MaxTransferSize = USB_ETH_MTU + 58; /* Space for 1280 IP buffer, Ethernet Header,
  286. RNDIS messages */
  287. resp->PacketAlignmentFactor = 3;
  288. resp->AfListOffset = 0;
  289. resp->AfListSize = 0;
  290. response->buffer = resp;
  291. {
  292. rt_base_t level = rt_hw_interrupt_disable();
  293. rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
  294. rt_hw_interrupt_enable(level);
  295. }
  296. return RT_EOK;
  297. }
  298. static rndis_query_cmplt_t _create_resp(rt_size_t size)
  299. {
  300. rndis_query_cmplt_t resp;
  301. resp = rt_malloc(sizeof(struct rndis_query_cmplt) + size);
  302. if(resp == RT_NULL)
  303. {
  304. RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
  305. return RT_NULL;
  306. }
  307. resp->InformationBufferLength = size;
  308. return resp;
  309. }
  310. static void _copy_resp(rndis_query_cmplt_t resp, const void * buffer)
  311. {
  312. char * resp_buffer = (char *)resp + sizeof(struct rndis_query_cmplt);
  313. memcpy(resp_buffer, buffer, resp->InformationBufferLength);
  314. }
  315. static void _set_resp(rndis_query_cmplt_t resp, rt_uint32_t value)
  316. {
  317. rt_uint32_t * response = (rt_uint32_t *)((char *)resp + sizeof(struct rndis_query_cmplt));
  318. *response = value;
  319. }
  320. static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
  321. {
  322. rndis_query_cmplt_t resp = RT_NULL;
  323. struct rt_rndis_response * response;
  324. rt_err_t ret = RT_EOK;
  325. switch (msg->Oid)
  326. {
  327. /*
  328. * general OIDs
  329. */
  330. case OID_GEN_SUPPORTED_LIST:
  331. resp = _create_resp(sizeof(oid_supported_list));
  332. if(resp == RT_NULL) break;
  333. _copy_resp(resp, oid_supported_list);
  334. break;
  335. case OID_GEN_PHYSICAL_MEDIUM:
  336. resp = _create_resp(4);
  337. if(resp == RT_NULL) break;
  338. _set_resp(resp, NDIS_MEDIUM_802_3);
  339. break;
  340. case OID_GEN_MAXIMUM_FRAME_SIZE:
  341. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  342. case OID_GEN_RECEIVE_BLOCK_SIZE:
  343. resp = _create_resp(4);
  344. if(resp == RT_NULL) break;
  345. _set_resp(resp, USB_ETH_MTU);
  346. break;
  347. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  348. resp = _create_resp(4);
  349. if(resp == RT_NULL) break;
  350. _set_resp(resp, USB_ETH_MTU + RNDIS_MESSAGE_BUFFER_SIZE);
  351. break;
  352. case OID_GEN_LINK_SPEED:
  353. resp = _create_resp(4);
  354. if(resp == RT_NULL) break;
  355. _set_resp(resp, func->device->dcd->device_is_hs ? (480UL * 1000 *1000) : (12UL * 1000 * 1000) / 100);
  356. break;
  357. case OID_GEN_MEDIA_CONNECT_STATUS:
  358. /* link_status */
  359. resp = _create_resp(4);
  360. if(resp == RT_NULL) break;
  361. #ifdef RNDIS_DELAY_LINK_UP
  362. if(((rt_rndis_eth_t)func->user_data)->parent.link_status)
  363. {
  364. _set_resp(resp, NDIS_MEDIA_STATE_CONNECTED);
  365. }
  366. else
  367. {
  368. _set_resp(resp, NDIS_MEDIA_STATE_DISCONNECTED);
  369. }
  370. #else
  371. _set_resp(resp, NDIS_MEDIA_STATE_CONNECTED);
  372. #endif /* RNDIS_DELAY_LINK_UP */
  373. break;
  374. case OID_GEN_VENDOR_ID:
  375. resp = _create_resp(4);
  376. if(resp == RT_NULL) break;
  377. _set_resp(resp, 0x12345678); /* only for test */
  378. break;
  379. case OID_GEN_VENDOR_DESCRIPTION:
  380. {
  381. const char vendor_desc[] = "RT-Thread RNDIS";
  382. resp = _create_resp(sizeof(vendor_desc));
  383. if(resp == RT_NULL) break;
  384. _copy_resp(resp, vendor_desc);
  385. }
  386. break;
  387. case OID_GEN_VENDOR_DRIVER_VERSION:
  388. resp = _create_resp(4);
  389. if(resp == RT_NULL) break;
  390. _set_resp(resp, 0x0000200);
  391. break;
  392. /* statistics OIDs */
  393. case OID_GEN_XMIT_OK:
  394. case OID_GEN_RCV_OK:
  395. resp = _create_resp(4);
  396. if(resp == RT_NULL) break;
  397. _set_resp(resp, 1);
  398. break;
  399. case OID_GEN_XMIT_ERROR:
  400. case OID_GEN_RCV_ERROR:
  401. case OID_GEN_RCV_NO_BUFFER:
  402. resp = _create_resp(4);
  403. if(resp == RT_NULL) break;
  404. _set_resp(resp, 0);
  405. break;
  406. /*
  407. * ieee802.3 OIDs
  408. */
  409. case OID_802_3_MAXIMUM_LIST_SIZE:
  410. resp = _create_resp(4);
  411. if(resp == RT_NULL) break;
  412. _set_resp(resp, 1);
  413. break;
  414. case OID_802_3_PERMANENT_ADDRESS:
  415. case OID_802_3_CURRENT_ADDRESS:
  416. resp = _create_resp(sizeof(((rt_rndis_eth_t)func->user_data)->host_addr));
  417. if(resp == RT_NULL) break;
  418. _copy_resp(resp, ((rt_rndis_eth_t)func->user_data)->host_addr);
  419. break;
  420. case OID_802_3_MULTICAST_LIST:
  421. resp = _create_resp(4);
  422. if(resp == RT_NULL) break;
  423. _set_resp(resp, 0xE000000);
  424. break;
  425. case OID_802_3_MAC_OPTIONS:
  426. resp = _create_resp(4);
  427. if(resp == RT_NULL) break;
  428. _set_resp(resp, 0);
  429. break;
  430. default:
  431. RNDIS_PRINTF("OID %X\n", msg->Oid);
  432. ret = -RT_ERROR;
  433. break;
  434. }
  435. response = rt_malloc(sizeof(struct rt_rndis_response));
  436. if( (response == RT_NULL) || (resp == RT_NULL) )
  437. {
  438. RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
  439. if(response != RT_NULL)
  440. rt_free(response);
  441. if(resp != RT_NULL)
  442. rt_free(resp);
  443. return -RT_ENOMEM;
  444. }
  445. resp->RequestId = msg->RequestId;
  446. resp->MessageType = REMOTE_NDIS_QUERY_CMPLT;
  447. resp->InformationBufferOffset = 16;
  448. resp->Status = RNDIS_STATUS_SUCCESS;
  449. resp->MessageLength = sizeof(struct rndis_query_cmplt) + resp->InformationBufferLength;
  450. response->buffer = resp;
  451. {
  452. rt_base_t level = rt_hw_interrupt_disable();
  453. rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
  454. rt_hw_interrupt_enable(level);
  455. }
  456. return ret;
  457. }
  458. static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
  459. {
  460. rndis_set_cmplt_t resp;
  461. struct rt_rndis_response * response;
  462. response = rt_malloc(sizeof(struct rt_rndis_response));
  463. resp = rt_malloc(sizeof(struct rndis_set_cmplt));
  464. if( (response == RT_NULL) || (resp == RT_NULL) )
  465. {
  466. RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
  467. if(response != RT_NULL)
  468. rt_free(response);
  469. if(resp != RT_NULL)
  470. rt_free(resp);
  471. return -RT_ENOMEM;
  472. }
  473. resp->RequestId = msg->RequestId;
  474. resp->MessageType = REMOTE_NDIS_SET_CMPLT;
  475. resp->MessageLength = sizeof(struct rndis_set_cmplt);
  476. switch (msg->Oid)
  477. {
  478. case OID_GEN_CURRENT_PACKET_FILTER:
  479. oid_packet_filter = *((rt_uint32_t *)((rt_uint8_t *)&(msg->RequestId) + \
  480. msg->InformationBufferOffset));
  481. oid_packet_filter = oid_packet_filter;
  482. RNDIS_PRINTF("OID_GEN_CURRENT_PACKET_FILTER\r\n");
  483. #ifdef RNDIS_DELAY_LINK_UP
  484. /* link up. */
  485. rt_timer_start(&((rt_rndis_eth_t)func->user_data)->timer);
  486. #else
  487. eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_TRUE);
  488. #endif /* RNDIS_DELAY_LINK_UP */
  489. break;
  490. case OID_802_3_MULTICAST_LIST:
  491. break;
  492. default:
  493. resp->Status = RNDIS_STATUS_FAILURE;
  494. return RT_EOK;
  495. }
  496. resp->Status = RNDIS_STATUS_SUCCESS;
  497. response->buffer = resp;
  498. {
  499. rt_base_t level = rt_hw_interrupt_disable();
  500. rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
  501. rt_hw_interrupt_enable(level);
  502. }
  503. return RT_EOK;
  504. }
  505. static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t msg)
  506. {
  507. rndis_keepalive_cmplt_t resp;
  508. struct rt_rndis_response * response;
  509. response = rt_malloc(sizeof(struct rt_rndis_response));
  510. resp = rt_malloc(sizeof(struct rndis_keepalive_cmplt));
  511. if( (response == RT_NULL) || (resp == RT_NULL) )
  512. {
  513. RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
  514. if(response != RT_NULL)
  515. rt_free(response);
  516. if(resp != RT_NULL)
  517. rt_free(resp);
  518. return -RT_ENOMEM;
  519. }
  520. resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
  521. resp->MessageLength = sizeof(struct rndis_keepalive_cmplt);
  522. resp->Status = RNDIS_STATUS_SUCCESS;
  523. response->buffer = resp;
  524. {
  525. rt_base_t level = rt_hw_interrupt_disable();
  526. rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
  527. rt_hw_interrupt_enable(level);
  528. }
  529. return RT_EOK;
  530. }
  531. static rt_err_t _rndis_msg_parser(ufunction_t func, rt_uint8_t *msg)
  532. {
  533. rt_err_t ret = -RT_ERROR;
  534. switch (((rndis_gen_msg_t) msg)->MessageType)
  535. {
  536. case REMOTE_NDIS_INITIALIZE_MSG:
  537. ret = _rndis_init_response(func, (rndis_init_msg_t) msg);
  538. break;
  539. case REMOTE_NDIS_HALT_MSG:
  540. RNDIS_PRINTF("halt\n");
  541. /* link down. */
  542. eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
  543. break;
  544. case REMOTE_NDIS_QUERY_MSG:
  545. ret = _rndis_query_response(func,(rndis_query_msg_t) msg);
  546. break;
  547. case REMOTE_NDIS_SET_MSG:
  548. ret = _rndis_set_response(func,(rndis_set_msg_t) msg);
  549. RNDIS_PRINTF("set\n");
  550. break;
  551. case REMOTE_NDIS_RESET_MSG:
  552. RNDIS_PRINTF("reset\n");
  553. break;
  554. case REMOTE_NDIS_KEEPALIVE_MSG:
  555. ret = _rndis_keepalive_response(func,(rndis_keepalive_msg_t) msg);
  556. break;
  557. default:
  558. RNDIS_PRINTF("msg %X\n", ((rndis_gen_msg_t) msg)->MessageType);
  559. ret = -RT_ERROR;
  560. break;
  561. }
  562. if (ret == RT_EOK)
  563. _rndis_response_available(func);
  564. return ret;
  565. }
  566. static ufunction_t function = RT_NULL;
  567. static rt_err_t send_encapsulated_command_done(udevice_t device, rt_size_t size)
  568. {
  569. if(function != RT_NULL)
  570. {
  571. dcd_ep0_send_status(device->dcd);
  572. _rndis_msg_parser(function, rndis_message_buffer);
  573. function = RT_NULL;
  574. }
  575. return RT_EOK;
  576. }
  577. //#error here have bug ep 0x82 send failed
  578. static rt_err_t _rndis_send_encapsulated_command(ufunction_t func, ureq_t setup)
  579. {
  580. RT_ASSERT(setup->wLength <= sizeof(rndis_message_buffer));
  581. function = func;
  582. rt_usbd_ep0_read(func->device,rndis_message_buffer,setup->wLength,send_encapsulated_command_done);
  583. return RT_EOK;
  584. }
  585. static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
  586. {
  587. rndis_gen_msg_t msg;
  588. struct rt_rndis_response * response;
  589. if(rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
  590. {
  591. RNDIS_PRINTF("response_list is empty!\r\n");
  592. ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
  593. return RT_EOK;
  594. }
  595. response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
  596. msg = (rndis_gen_msg_t)response->buffer;
  597. rt_usbd_ep0_write(func->device, (void*)msg, msg->MessageLength);
  598. {
  599. rt_base_t level = rt_hw_interrupt_disable();
  600. rt_list_remove(&response->list);
  601. rt_hw_interrupt_enable(level);
  602. }
  603. rt_free((void *)response->buffer);
  604. rt_free(response);
  605. if(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
  606. {
  607. rt_uint32_t * data;
  608. RNDIS_PRINTF("auto append next response!\r\n");
  609. data = (rt_uint32_t *)((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer;
  610. data[0] = RESPONSE_AVAILABLE;
  611. data[1] = 0;
  612. ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request.buffer = ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer;
  613. ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request.size = 8;
  614. ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request.req_type = UIO_REQUEST_WRITE;
  615. rt_usbd_io_request(func->device, ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd, &((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request);
  616. }
  617. else
  618. {
  619. ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
  620. }
  621. return RT_EOK;
  622. }
  623. #ifdef RNDIS_DELAY_LINK_UP
  624. /**
  625. * This function will set rndis connect status.
  626. *
  627. * @param device the usb device object.
  628. * @param status the connect status.
  629. *
  630. * @return RT_EOK on successful.
  631. */
  632. static rt_err_t _rndis_indicate_status_msg(ufunction_t func, rt_uint32_t status)
  633. {
  634. rndis_indicate_status_msg_t resp;
  635. struct rt_rndis_response * response;
  636. response = rt_malloc(sizeof(struct rt_rndis_response));
  637. resp = rt_malloc(sizeof(struct rndis_indicate_status_msg));
  638. if( (response == RT_NULL) || (resp == RT_NULL) )
  639. {
  640. RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
  641. if(response != RT_NULL)
  642. rt_free(response);
  643. if(resp != RT_NULL)
  644. rt_free(resp);
  645. return -RT_ENOMEM;
  646. }
  647. resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
  648. resp->MessageLength = 20; /* sizeof(struct rndis_indicate_status_msg) */
  649. resp->Status = status;
  650. resp->StatusBufferLength = 0;
  651. resp->StatusBufferOffset = 0;
  652. response->buffer = resp;
  653. {
  654. rt_base_t level = rt_hw_interrupt_disable();
  655. rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
  656. rt_hw_interrupt_enable(level);
  657. }
  658. _rndis_response_available(func);
  659. return RT_EOK;
  660. }
  661. #endif /* RNDIS_DELAY_LINK_UP */
  662. /**
  663. * This function will handle rndis interface request.
  664. *
  665. * @param device the usb device object.
  666. * @param setup the setup request.
  667. *
  668. * @return RT_EOK on successful.
  669. */
  670. static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
  671. {
  672. RT_ASSERT(func != RT_NULL);
  673. RT_ASSERT(setup != RT_NULL);
  674. switch(setup->bRequest)
  675. {
  676. case CDC_SEND_ENCAPSULATED_COMMAND:
  677. _rndis_send_encapsulated_command(func, setup);
  678. break;
  679. case CDC_GET_ENCAPSULATED_RESPONSE:
  680. _rndis_get_encapsulated_response(func, setup);
  681. break;
  682. default:
  683. RNDIS_PRINTF("unkown setup->request!\r\n");
  684. break;
  685. }
  686. return RT_EOK;
  687. }
  688. /**
  689. * This function will handle rndis bulk in endpoint request.
  690. *
  691. * @param device the usb device object.
  692. * @param size request size.
  693. *
  694. * @return RT_EOK.
  695. */
  696. static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size)
  697. {
  698. rt_sem_release(&((rt_rndis_eth_t)func->user_data)->tx_buffer_free);
  699. return RT_EOK;
  700. }
  701. /**
  702. * This function will handle RNDIS bulk out endpoint request.
  703. *
  704. * @param device the usb device object.
  705. * @param size request size.
  706. *
  707. * @return RT_EOK.
  708. */
  709. static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size)
  710. {
  711. cdc_eps_t eps;
  712. char* data = RT_NULL;
  713. eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps;
  714. data = (char*)eps->ep_out->buffer;
  715. if(((rt_rndis_eth_t)func->user_data)->rx_frist == RT_TRUE)
  716. {
  717. rndis_packet_msg_t msg = (rndis_packet_msg_t)data;
  718. ((rt_rndis_eth_t)func->user_data)->rx_length = msg->DataLength;
  719. ((rt_rndis_eth_t)func->user_data)->rx_offset = 0;
  720. if (size >= 44)
  721. {
  722. data += sizeof(struct rndis_packet_msg);
  723. size -= sizeof(struct rndis_packet_msg);
  724. ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_FALSE;
  725. memcpy(&((rt_rndis_eth_t)func->user_data)->rx_buffer[((rt_rndis_eth_t)func->user_data)->rx_offset], data, size);
  726. ((rt_rndis_eth_t)func->user_data)->rx_offset += size;
  727. }
  728. }
  729. else
  730. {
  731. memcpy(&((rt_rndis_eth_t)func->user_data)->rx_buffer[((rt_rndis_eth_t)func->user_data)->rx_offset], data, size);
  732. ((rt_rndis_eth_t)func->user_data)->rx_offset += size;
  733. }
  734. if(((rt_rndis_eth_t)func->user_data)->rx_offset >= ((rt_rndis_eth_t)func->user_data)->rx_length)
  735. {
  736. ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
  737. ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_TRUE;
  738. eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent));
  739. }
  740. else
  741. {
  742. eps->ep_out->request.buffer = eps->ep_out->buffer;
  743. eps->ep_out->request.size = EP_MAXPACKET(eps->ep_out);
  744. eps->ep_out->request.req_type = UIO_REQUEST_READ_BEST;
  745. rt_usbd_io_request(func->device, eps->ep_out, &eps->ep_out->request);
  746. }
  747. return RT_EOK;
  748. }
  749. /**
  750. * This function will handle RNDIS interrupt in endpoint request.
  751. *
  752. * @param device the usb device object.
  753. * @param size request size.
  754. *
  755. * @return RT_EOK.
  756. */
  757. static rt_err_t _ep_cmd_handler(ufunction_t func, rt_size_t size)
  758. {
  759. // _rndis_response_available(func);
  760. return RT_EOK;
  761. }
  762. /**
  763. * This function will run cdc class, it will be called on handle set configuration request.
  764. *
  765. * @param device the usb device object.
  766. *
  767. * @return RT_EOK on successful.
  768. */
  769. static rt_err_t _function_enable(ufunction_t func)
  770. {
  771. cdc_eps_t eps;
  772. eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps;
  773. eps->ep_in->buffer = ((rt_rndis_eth_t)func->user_data)->tx_pool;
  774. eps->ep_out->buffer = ((rt_rndis_eth_t)func->user_data)->rx_pool;
  775. eps->ep_cmd->buffer = (rt_uint8_t*)((rt_rndis_eth_t)func->user_data)->cmd_pool;
  776. eps->ep_out->request.buffer = eps->ep_out->buffer;
  777. eps->ep_out->request.size = EP_MAXPACKET(eps->ep_out);
  778. eps->ep_out->request.req_type = UIO_REQUEST_READ_BEST;
  779. rt_usbd_io_request(func->device, eps->ep_out, &eps->ep_out->request);
  780. ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
  781. ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
  782. #ifdef RNDIS_DELAY_LINK_UP
  783. /* stop link up timer. */
  784. rt_timer_stop(&((rt_rndis_eth_t)func->user_data)->timer);
  785. #endif /* RNDIS_DELAY_LINK_UP */
  786. /* clean resp chain list. */
  787. {
  788. struct rt_rndis_response * response;
  789. rt_base_t level = rt_hw_interrupt_disable();
  790. while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
  791. {
  792. response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
  793. rt_list_remove(&response->list);
  794. rt_free((void *)response->buffer);
  795. rt_free(response);
  796. }
  797. ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
  798. rt_hw_interrupt_enable(level);
  799. }
  800. return RT_EOK;
  801. }
  802. /**
  803. * This function will stop cdc class, it will be called on handle set configuration request.
  804. *
  805. * @param device the usb device object.
  806. *
  807. * @return RT_EOK on successful.
  808. */
  809. static rt_err_t _function_disable(ufunction_t func)
  810. {
  811. RNDIS_PRINTF("plugged out\n");
  812. #ifdef RNDIS_DELAY_LINK_UP
  813. /* stop link up timer. */
  814. rt_timer_stop(&((rt_rndis_eth_t)func->user_data)->timer);
  815. #endif /* RNDIS_DELAY_LINK_UP */
  816. /* clean resp chain list. */
  817. {
  818. struct rt_rndis_response * response;
  819. rt_base_t level = rt_hw_interrupt_disable();
  820. while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
  821. {
  822. response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
  823. RNDIS_PRINTF("remove resp chain list!\r\n");
  824. rt_list_remove(&response->list);
  825. rt_free((void *)response->buffer);
  826. rt_free(response);
  827. }
  828. ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
  829. rt_hw_interrupt_enable(level);
  830. }
  831. /* link down. */
  832. eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
  833. return RT_EOK;
  834. }
  835. static struct ufunction_ops ops =
  836. {
  837. _function_enable,
  838. _function_disable,
  839. RT_NULL,
  840. };
  841. /**
  842. * This function will configure cdc descriptor.
  843. *
  844. * @param comm the communication interface number.
  845. * @param data the data interface number.
  846. *
  847. * @return RT_EOK on successful.
  848. */
  849. static rt_err_t _cdc_descriptor_config(ucdc_comm_desc_t comm, rt_uint8_t cintf_nr, ucdc_data_desc_t data, rt_uint8_t dintf_nr, rt_uint8_t device_is_hs)
  850. {
  851. comm->call_mgmt_desc.data_interface = dintf_nr;
  852. comm->union_desc.master_interface = cintf_nr;
  853. comm->union_desc.slave_interface0 = dintf_nr;
  854. #ifdef RT_USB_DEVICE_COMPOSITE
  855. comm->iad_desc.bFirstInterface = cintf_nr;
  856. #endif
  857. data->ep_out_desc.wMaxPacketSize = device_is_hs ? 512 : 64;
  858. data->ep_in_desc.wMaxPacketSize = device_is_hs ? 512 : 64;
  859. return RT_EOK;
  860. }
  861. #ifdef RT_USING_LWIP
  862. /* initialize the interface */
  863. static rt_err_t rt_rndis_eth_init(rt_device_t dev)
  864. {
  865. return RT_EOK;
  866. }
  867. static rt_err_t rt_rndis_eth_open(rt_device_t dev, rt_uint16_t oflag)
  868. {
  869. return RT_EOK;
  870. }
  871. static rt_err_t rt_rndis_eth_close(rt_device_t dev)
  872. {
  873. return RT_EOK;
  874. }
  875. static rt_size_t rt_rndis_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  876. {
  877. rt_set_errno(-RT_ENOSYS);
  878. return 0;
  879. }
  880. static rt_size_t rt_rndis_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  881. {
  882. rt_set_errno(-RT_ENOSYS);
  883. return 0;
  884. }
  885. static rt_err_t rt_rndis_eth_control(rt_device_t dev, int cmd, void *args)
  886. {
  887. rt_rndis_eth_t rndis_eth_dev = (rt_rndis_eth_t)dev;
  888. switch(cmd)
  889. {
  890. case NIOCTL_GADDR:
  891. /* get mac address */
  892. if(args) rt_memcpy(args, rndis_eth_dev->dev_addr, MAX_ADDR_LEN);
  893. else return -RT_ERROR;
  894. break;
  895. default :
  896. break;
  897. }
  898. return RT_EOK;
  899. }
  900. /* ethernet device interface */
  901. /* reception packet. */
  902. struct pbuf *rt_rndis_eth_rx(rt_device_t dev)
  903. {
  904. struct pbuf* p = RT_NULL;
  905. rt_uint32_t offset = 0;
  906. rt_rndis_eth_t device = (rt_rndis_eth_t)dev;
  907. if(device->rx_flag == RT_FALSE)
  908. {
  909. return p;
  910. }
  911. if(device->rx_length != 0)
  912. {
  913. /* allocate buffer */
  914. p = pbuf_alloc(PBUF_LINK, device->rx_length, PBUF_RAM);
  915. if (p != RT_NULL)
  916. {
  917. struct pbuf* q;
  918. for (q = p; q != RT_NULL; q= q->next)
  919. {
  920. /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */
  921. memcpy(q->payload,
  922. (rt_uint8_t *)((device->rx_buffer) + offset),
  923. q->len);
  924. offset += q->len;
  925. }
  926. }
  927. }
  928. {
  929. device->rx_flag = RT_FALSE;
  930. device->eps.ep_out->request.buffer = device->eps.ep_out->buffer;
  931. device->eps.ep_out->request.size = EP_MAXPACKET(device->eps.ep_out);
  932. device->eps.ep_out->request.req_type = UIO_REQUEST_READ_BEST;
  933. rt_usbd_io_request(device->func->device, device->eps.ep_out, &device->eps.ep_out->request);
  934. }
  935. return p;
  936. }
  937. /* transmit packet. */
  938. rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf* p)
  939. {
  940. struct pbuf* q;
  941. char * buffer;
  942. rt_err_t result = RT_EOK;
  943. rt_rndis_eth_t device = (rt_rndis_eth_t)dev;
  944. if(!device->parent.link_status)
  945. {
  946. RNDIS_PRINTF("linkdown, drop pkg\r\n");
  947. return RT_EOK;
  948. }
  949. RT_ASSERT(p->tot_len < sizeof(device->tx_buffer));
  950. if(p->tot_len > sizeof(device->tx_buffer))
  951. {
  952. RNDIS_PRINTF("RNDIS MTU is:%d, but the send packet size is %d\r\n",
  953. sizeof(device->tx_buffer), p->tot_len);
  954. p->tot_len = sizeof(device->tx_buffer);
  955. }
  956. /* wait for buffer free. */
  957. result = rt_sem_take(&device->tx_buffer_free, RT_WAITING_FOREVER);
  958. if(result != RT_EOK)
  959. {
  960. return result;
  961. }
  962. buffer = (char *)&device->tx_buffer + sizeof(struct rndis_packet_msg);
  963. for (q = p; q != NULL; q = q->next)
  964. {
  965. memcpy(buffer, q->payload, q->len);
  966. buffer += q->len;
  967. }
  968. /* send */
  969. {
  970. rndis_packet_msg_t msg;
  971. msg = (rndis_packet_msg_t)&device->tx_buffer;
  972. msg->MessageType = REMOTE_NDIS_PACKET_MSG;
  973. msg->DataOffset = sizeof(struct rndis_packet_msg) - 8;
  974. msg->DataLength = p->tot_len;
  975. msg->OOBDataLength = 0;
  976. msg->OOBDataOffset = 0;
  977. msg->NumOOBDataElements = 0;
  978. msg->PerPacketInfoOffset = 0;
  979. msg->PerPacketInfoLength = 0;
  980. msg->VcHandle = 0;
  981. msg->Reserved = 0;
  982. msg->MessageLength = sizeof(struct rndis_packet_msg) + p->tot_len;
  983. if((msg->MessageLength & 0x3F) == 0)
  984. {
  985. /* pad a dummy. */
  986. msg->MessageLength += 1;
  987. }
  988. device->eps.ep_in->request.buffer = (void *)&device->tx_buffer;
  989. device->eps.ep_in->request.size = msg->MessageLength;
  990. device->eps.ep_in->request.req_type = UIO_REQUEST_WRITE;
  991. rt_usbd_io_request(device->func->device, device->eps.ep_in, &device->eps.ep_in->request);
  992. }
  993. return result;
  994. }
  995. #endif /* RT_USING_LWIP */
  996. #ifdef RNDIS_DELAY_LINK_UP
  997. /* the delay linkup timer handler. */
  998. static void timer_timeout(void* parameter)
  999. {
  1000. RNDIS_PRINTF("delay link up!\r\n");
  1001. _rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->parent.parent.user_data,
  1002. RNDIS_STATUS_MEDIA_CONNECT);
  1003. eth_device_linkchange(&((rt_rndis_eth_t)parameter)->parent, RT_TRUE);
  1004. }
  1005. #endif /* RNDIS_DELAY_LINK_UP */
  1006. /**
  1007. * This function will create a cdc rndis class instance.
  1008. *
  1009. * @param device the usb device object.
  1010. *
  1011. * @return RT_EOK on successful.
  1012. */
  1013. ufunction_t rt_usbd_function_rndis_create(udevice_t device)
  1014. {
  1015. ufunction_t cdc;
  1016. rt_rndis_eth_t _rndis;
  1017. cdc_eps_t eps;
  1018. uintf_t intf_comm, intf_data;
  1019. ualtsetting_t comm_setting, data_setting;
  1020. ucdc_data_desc_t data_desc;
  1021. ucdc_comm_desc_t comm_desc;
  1022. /* parameter check */
  1023. RT_ASSERT(device != RT_NULL);
  1024. /* set usb device string description */
  1025. rt_usbd_device_set_string(device, _ustring);
  1026. /* create a cdc class */
  1027. cdc = rt_usbd_function_new(device, &_dev_desc, &ops);
  1028. rt_usbd_device_set_qualifier(device, &dev_qualifier);
  1029. _rndis= rt_malloc(sizeof(struct rt_rndis_eth));
  1030. rt_memset(_rndis, 0, sizeof(struct rt_rndis_eth));
  1031. cdc->user_data = _rndis;
  1032. _rndis->func = cdc;
  1033. /* create a cdc class endpoints collection */
  1034. eps = &_rndis->eps;
  1035. /* create a cdc communication interface and a cdc data interface */
  1036. intf_comm = rt_usbd_interface_new(device, _interface_handler);
  1037. intf_data = rt_usbd_interface_new(device, _interface_handler);
  1038. /* create a communication alternate setting and a data alternate setting */
  1039. comm_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_comm_descriptor));
  1040. data_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_data_descriptor));
  1041. /* config desc in alternate setting */
  1042. rt_usbd_altsetting_config_descriptor(comm_setting, &_comm_desc,
  1043. (rt_off_t)&((ucdc_comm_desc_t)0)->intf_desc);
  1044. rt_usbd_altsetting_config_descriptor(data_setting, &_data_desc, 0);
  1045. /* configure the cdc interface descriptor */
  1046. _cdc_descriptor_config(comm_setting->desc, intf_comm->intf_num, data_setting->desc, intf_data->intf_num, device->dcd->device_is_hs);
  1047. /* create a command endpoint */
  1048. comm_desc = (ucdc_comm_desc_t)comm_setting->desc;
  1049. eps->ep_cmd = rt_usbd_endpoint_new(&comm_desc->ep_desc, _ep_cmd_handler);
  1050. /* add the command endpoint to the cdc communication interface */
  1051. rt_usbd_altsetting_add_endpoint(comm_setting, eps->ep_cmd);
  1052. /* add the communication alternate setting to the communication interface,
  1053. then set default setting of the interface */
  1054. rt_usbd_interface_add_altsetting(intf_comm, comm_setting);
  1055. rt_usbd_set_altsetting(intf_comm, 0);
  1056. /* add the communication interface to the cdc class */
  1057. rt_usbd_function_add_interface(cdc, intf_comm);
  1058. /* create a bulk in and a bulk out endpoint */
  1059. data_desc = (ucdc_data_desc_t)data_setting->desc;
  1060. eps->ep_out = rt_usbd_endpoint_new(&data_desc->ep_out_desc, _ep_out_handler);
  1061. eps->ep_in = rt_usbd_endpoint_new(&data_desc->ep_in_desc, _ep_in_handler);
  1062. /* add the bulk out and bulk in endpoints to the data alternate setting */
  1063. rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_in);
  1064. rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_out);
  1065. /* add the data alternate setting to the data interface
  1066. then set default setting of the interface */
  1067. rt_usbd_interface_add_altsetting(intf_data, data_setting);
  1068. rt_usbd_set_altsetting(intf_data, 0);
  1069. /* add the cdc data interface to cdc class */
  1070. rt_usbd_function_add_interface(cdc, intf_data);
  1071. rt_usbd_os_comp_id_desc_add_os_func_comp_id_desc(device->os_comp_id_desc, &rndis_func_comp_id_desc);
  1072. #ifdef RT_USING_LWIP
  1073. rt_list_init(&_rndis->response_list);
  1074. _rndis->need_notify = RT_TRUE;
  1075. rt_sem_init(&_rndis->tx_buffer_free, "ue_tx", 1, RT_IPC_FLAG_FIFO);
  1076. #ifdef RNDIS_DELAY_LINK_UP
  1077. rt_timer_init(&_rndis->timer,
  1078. "RNDIS",
  1079. timer_timeout,
  1080. _rndis,
  1081. RT_TICK_PER_SECOND * 2,
  1082. RT_TIMER_FLAG_ONE_SHOT);
  1083. #endif /* RNDIS_DELAY_LINK_UP */
  1084. /* OUI 00-00-00, only for test. */
  1085. _rndis->dev_addr[0] = 0x34;
  1086. _rndis->dev_addr[1] = 0x97;
  1087. _rndis->dev_addr[2] = 0xF6;
  1088. /* generate random MAC. */
  1089. _rndis->dev_addr[3] = 0x94;//*(const rt_uint8_t *)(0x1fff7a10);
  1090. _rndis->dev_addr[4] = 0xEA;//*(const rt_uint8_t *)(0x1fff7a14);
  1091. _rndis->dev_addr[5] = 0x12;//(const rt_uint8_t *)(0x1fff7a18);
  1092. /* OUI 00-00-00, only for test. */
  1093. _rndis->host_addr[0] = 0x34;
  1094. _rndis->host_addr[1] = 0x97;
  1095. _rndis->host_addr[2] = 0xF6;
  1096. /* generate random MAC. */
  1097. _rndis->host_addr[3] = 0x94;//*(const rt_uint8_t *)(0x0FE081F0);
  1098. _rndis->host_addr[4] = 0xEA;//*(const rt_uint8_t *)(0x0FE081F1);
  1099. _rndis->host_addr[5] = 0x13;//*(const rt_uint8_t *)(0x0FE081F2);
  1100. _rndis->parent.parent.init = rt_rndis_eth_init;
  1101. _rndis->parent.parent.open = rt_rndis_eth_open;
  1102. _rndis->parent.parent.close = rt_rndis_eth_close;
  1103. _rndis->parent.parent.read = rt_rndis_eth_read;
  1104. _rndis->parent.parent.write = rt_rndis_eth_write;
  1105. _rndis->parent.parent.control = rt_rndis_eth_control;
  1106. _rndis->parent.parent.user_data = device;
  1107. _rndis->parent.eth_rx = rt_rndis_eth_rx;
  1108. _rndis->parent.eth_tx = rt_rndis_eth_tx;
  1109. /* register eth device */
  1110. eth_device_init(&((rt_rndis_eth_t)cdc->user_data)->parent, "u0");
  1111. #endif /* RT_USING_LWIP */
  1112. return cdc;
  1113. }