rndis.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  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. #ifdef RT_USING_DEVICE_OPS
  996. const static struct rt_device_ops rndis_device_ops =
  997. {
  998. rt_rndis_eth_init,
  999. rt_rndis_eth_open,
  1000. rt_rndis_eth_close,
  1001. rt_rndis_eth_read,
  1002. rt_rndis_eth_write,
  1003. rt_rndis_eth_control
  1004. };
  1005. #endif
  1006. #endif /* RT_USING_LWIP */
  1007. #ifdef RNDIS_DELAY_LINK_UP
  1008. /* the delay linkup timer handler. */
  1009. static void timer_timeout(void* parameter)
  1010. {
  1011. RNDIS_PRINTF("delay link up!\r\n");
  1012. _rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->parent.parent.user_data,
  1013. RNDIS_STATUS_MEDIA_CONNECT);
  1014. eth_device_linkchange(&((rt_rndis_eth_t)parameter)->parent, RT_TRUE);
  1015. }
  1016. #endif /* RNDIS_DELAY_LINK_UP */
  1017. /**
  1018. * This function will create a cdc rndis class instance.
  1019. *
  1020. * @param device the usb device object.
  1021. *
  1022. * @return RT_EOK on successful.
  1023. */
  1024. ufunction_t rt_usbd_function_rndis_create(udevice_t device)
  1025. {
  1026. ufunction_t cdc;
  1027. rt_rndis_eth_t _rndis;
  1028. cdc_eps_t eps;
  1029. uintf_t intf_comm, intf_data;
  1030. ualtsetting_t comm_setting, data_setting;
  1031. ucdc_data_desc_t data_desc;
  1032. ucdc_comm_desc_t comm_desc;
  1033. /* parameter check */
  1034. RT_ASSERT(device != RT_NULL);
  1035. /* set usb device string description */
  1036. rt_usbd_device_set_string(device, _ustring);
  1037. /* create a cdc class */
  1038. cdc = rt_usbd_function_new(device, &_dev_desc, &ops);
  1039. rt_usbd_device_set_qualifier(device, &dev_qualifier);
  1040. _rndis= rt_malloc(sizeof(struct rt_rndis_eth));
  1041. rt_memset(_rndis, 0, sizeof(struct rt_rndis_eth));
  1042. cdc->user_data = _rndis;
  1043. _rndis->func = cdc;
  1044. /* create a cdc class endpoints collection */
  1045. eps = &_rndis->eps;
  1046. /* create a cdc communication interface and a cdc data interface */
  1047. intf_comm = rt_usbd_interface_new(device, _interface_handler);
  1048. intf_data = rt_usbd_interface_new(device, _interface_handler);
  1049. /* create a communication alternate setting and a data alternate setting */
  1050. comm_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_comm_descriptor));
  1051. data_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_data_descriptor));
  1052. /* config desc in alternate setting */
  1053. rt_usbd_altsetting_config_descriptor(comm_setting, &_comm_desc,
  1054. (rt_off_t)&((ucdc_comm_desc_t)0)->intf_desc);
  1055. rt_usbd_altsetting_config_descriptor(data_setting, &_data_desc, 0);
  1056. /* configure the cdc interface descriptor */
  1057. _cdc_descriptor_config(comm_setting->desc, intf_comm->intf_num, data_setting->desc, intf_data->intf_num, device->dcd->device_is_hs);
  1058. /* create a command endpoint */
  1059. comm_desc = (ucdc_comm_desc_t)comm_setting->desc;
  1060. eps->ep_cmd = rt_usbd_endpoint_new(&comm_desc->ep_desc, _ep_cmd_handler);
  1061. /* add the command endpoint to the cdc communication interface */
  1062. rt_usbd_altsetting_add_endpoint(comm_setting, eps->ep_cmd);
  1063. /* add the communication alternate setting to the communication interface,
  1064. then set default setting of the interface */
  1065. rt_usbd_interface_add_altsetting(intf_comm, comm_setting);
  1066. rt_usbd_set_altsetting(intf_comm, 0);
  1067. /* add the communication interface to the cdc class */
  1068. rt_usbd_function_add_interface(cdc, intf_comm);
  1069. /* create a bulk in and a bulk out endpoint */
  1070. data_desc = (ucdc_data_desc_t)data_setting->desc;
  1071. eps->ep_out = rt_usbd_endpoint_new(&data_desc->ep_out_desc, _ep_out_handler);
  1072. eps->ep_in = rt_usbd_endpoint_new(&data_desc->ep_in_desc, _ep_in_handler);
  1073. /* add the bulk out and bulk in endpoints to the data alternate setting */
  1074. rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_in);
  1075. rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_out);
  1076. /* add the data alternate setting to the data interface
  1077. then set default setting of the interface */
  1078. rt_usbd_interface_add_altsetting(intf_data, data_setting);
  1079. rt_usbd_set_altsetting(intf_data, 0);
  1080. /* add the cdc data interface to cdc class */
  1081. rt_usbd_function_add_interface(cdc, intf_data);
  1082. rt_usbd_os_comp_id_desc_add_os_func_comp_id_desc(device->os_comp_id_desc, &rndis_func_comp_id_desc);
  1083. #ifdef RT_USING_LWIP
  1084. rt_list_init(&_rndis->response_list);
  1085. _rndis->need_notify = RT_TRUE;
  1086. rt_sem_init(&_rndis->tx_buffer_free, "ue_tx", 1, RT_IPC_FLAG_FIFO);
  1087. #ifdef RNDIS_DELAY_LINK_UP
  1088. rt_timer_init(&_rndis->timer,
  1089. "RNDIS",
  1090. timer_timeout,
  1091. _rndis,
  1092. RT_TICK_PER_SECOND * 2,
  1093. RT_TIMER_FLAG_ONE_SHOT);
  1094. #endif /* RNDIS_DELAY_LINK_UP */
  1095. /* OUI 00-00-00, only for test. */
  1096. _rndis->dev_addr[0] = 0x34;
  1097. _rndis->dev_addr[1] = 0x97;
  1098. _rndis->dev_addr[2] = 0xF6;
  1099. /* generate random MAC. */
  1100. _rndis->dev_addr[3] = 0x94;//*(const rt_uint8_t *)(0x1fff7a10);
  1101. _rndis->dev_addr[4] = 0xEA;//*(const rt_uint8_t *)(0x1fff7a14);
  1102. _rndis->dev_addr[5] = 0x12;//(const rt_uint8_t *)(0x1fff7a18);
  1103. /* OUI 00-00-00, only for test. */
  1104. _rndis->host_addr[0] = 0x34;
  1105. _rndis->host_addr[1] = 0x97;
  1106. _rndis->host_addr[2] = 0xF6;
  1107. /* generate random MAC. */
  1108. _rndis->host_addr[3] = 0x94;//*(const rt_uint8_t *)(0x0FE081F0);
  1109. _rndis->host_addr[4] = 0xEA;//*(const rt_uint8_t *)(0x0FE081F1);
  1110. _rndis->host_addr[5] = 0x13;//*(const rt_uint8_t *)(0x0FE081F2);
  1111. #ifdef RT_USING_DEVICE_OPS
  1112. _rndis->parent.parent.ops = &rndis_device_ops;
  1113. #else
  1114. _rndis->parent.parent.init = rt_rndis_eth_init;
  1115. _rndis->parent.parent.open = rt_rndis_eth_open;
  1116. _rndis->parent.parent.close = rt_rndis_eth_close;
  1117. _rndis->parent.parent.read = rt_rndis_eth_read;
  1118. _rndis->parent.parent.write = rt_rndis_eth_write;
  1119. _rndis->parent.parent.control = rt_rndis_eth_control;
  1120. #endif
  1121. _rndis->parent.parent.user_data = device;
  1122. _rndis->parent.eth_rx = rt_rndis_eth_rx;
  1123. _rndis->parent.eth_tx = rt_rndis_eth_tx;
  1124. /* register eth device */
  1125. eth_device_init(&((rt_rndis_eth_t)cdc->user_data)->parent, "u0");
  1126. #endif /* RT_USING_LWIP */
  1127. return cdc;
  1128. }
  1129. struct udclass rndis_class =
  1130. {
  1131. .rt_usbd_function_create = rt_usbd_function_rndis_create
  1132. };
  1133. int rt_usbd_rndis_class_register(void)
  1134. {
  1135. rt_usbd_class_register(&rndis_class);
  1136. return 0;
  1137. }
  1138. INIT_PREV_EXPORT(rt_usbd_rndis_class_register);