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