diff options
| author | Runcheng Lu <[email protected]> | 2023-06-16 10:26:38 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2023-06-16 10:43:49 +0800 |
| commit | f35b345680a5b80b032e4b67ec0d6331918eeb87 (patch) | |
| tree | 30555f553b33d32627b8993eb9386df70ed8ec14 | |
| parent | 56868b513ac1375b71770ec14b2e194e0073e9ca (diff) | |
third_party: rtthread: fix rndis_host some issue
- fix some issue
Signed-off-by: Runcheng Lu <[email protected]>
| -rw-r--r-- | third_party/rt-thread-4.1.1/rndis_host/rndis_host.c | 311 |
1 files changed, 125 insertions, 186 deletions
diff --git a/third_party/rt-thread-4.1.1/rndis_host/rndis_host.c b/third_party/rt-thread-4.1.1/rndis_host/rndis_host.c index 64707bca..79aa7517 100644 --- a/third_party/rt-thread-4.1.1/rndis_host/rndis_host.c +++ b/third_party/rt-thread-4.1.1/rndis_host/rndis_host.c @@ -29,7 +29,12 @@ /* rndis device keepalive time 5000ms*/ #define RNDIS_DEV_KEEPALIVE_TIMEOUT 5000 /*should be the usb Integer multiple of maximum packet length N*64*/ -#define RNDIS_ETH_BUFFER_LEN (sizeof(struct rndis_packet_msg) + USB_ETH_MTU + 42) +#define RNDIS_ETH_BUFFER_LEN ((sizeof(struct rndis_packet_msg) + USB_ETH_MTU + 42) * 5) + +struct usbh_user_rndis { + struct usbh_rndis *rndis_class; + void *user_data; +}; struct rndis_packet_msg { @@ -52,7 +57,7 @@ struct rt_rndis_eth { /* inherit from ethernet device */ struct eth_device parent; - struct usbh_rndis *rndis_class; + struct usbh_user_rndis *rndis_class; rt_mutex_t rndis_mutex; /* interface address info */ rt_uint8_t dev_addr[MAX_ADDR_LEN]; @@ -61,10 +66,7 @@ struct rt_rndis_eth { rt_uint32_t res32; rt_uint8_t tx_buffer[RNDIS_ETH_BUFFER_LEN]; - rt_uint8_t rx_bufferA[RNDIS_ETH_BUFFER_LEN]; - rt_uint8_t rx_bufferB[RNDIS_ETH_BUFFER_LEN]; - rt_size_t rx_lengthA; - rt_size_t rx_lengthB; + rt_uint8_t rx_buffer[RNDIS_ETH_BUFFER_LEN]; rt_uint8_t *rx_buf_ptr; rt_uint32_t frame_debug; rt_uint32_t send_packet_counter; @@ -76,6 +78,9 @@ struct rt_rndis_eth { }; typedef struct rt_rndis_eth *rt_rndis_eth_t; +struct usbh_user_rndis *g_user_rndis; +USB_NOCACHE_RAM_SECTION struct rt_rndis_eth usbh_rndis_eth_device; + void hex_data_print(const char *name, const rt_uint8_t *buf, rt_size_t size) { #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') @@ -121,8 +126,6 @@ void hex_data_print(const char *name, const rt_uint8_t *buf, rt_size_t size) #define RNDIS_DEV_PRINTF(...) #endif /* RNDIS_DEBUG */ -static struct rt_rndis_eth usbh_rndis_eth_device; - /** * This function send the rndis data. * @@ -130,7 +133,7 @@ static struct rt_rndis_eth usbh_rndis_eth_device; * * @return the error code, RT_EOK on successfully. */ -static rt_err_t rt_rndis_msg_data_send(struct usbh_rndis *rndis_class, rt_uint8_t *buffer, int nbytes) +static rt_err_t rt_rndis_msg_data_send(struct usbh_user_rndis *rndis_class, rt_uint8_t *buffer, int nbytes) { int ret = 0; @@ -141,17 +144,12 @@ static rt_err_t rt_rndis_msg_data_send(struct usbh_rndis *rndis_class, rt_uint8_ rt_rndis_eth_t info = RT_NULL; info = (rt_rndis_eth_t)rndis_class->user_data; - - ret = usbh_rndis_bulk_out_transfer(rndis_class, buffer, nbytes, 5000); + rt_mutex_take(usbh_rndis_eth_device.rndis_mutex, RT_WAITING_FOREVER); + ret = usbh_rndis_bulk_out_transfer(rndis_class->rndis_class, buffer, nbytes, 5000); + rt_mutex_release(usbh_rndis_eth_device.rndis_mutex); if (ret != nbytes) { rt_kprintf("rndis msg send fial\r\n"); } - rt_mutex_take(usbh_rndis_eth_device.rndis_mutex, RT_WAITING_FOREVER); - if (info->keepalive_timer) { - rt_timer_start(info->keepalive_timer); - } - rt_mutex_release(usbh_rndis_eth_device.rndis_mutex); - return ret; } @@ -162,24 +160,14 @@ static rt_err_t rt_rndis_msg_data_send(struct usbh_rndis *rndis_class, rt_uint8_ * * @return the error code, RT_EOK on successfully. */ -static rt_err_t rndis_msg_data_recv(struct usbh_rndis *rndis_class, rt_uint8_t *buffer, int nbytes) +static rt_err_t rndis_msg_data_recv(struct usbh_user_rndis *rndis_class, rt_uint8_t *buffer, int nbytes) { int ret = 0; if (rndis_class == RT_NULL) { return -RT_ERROR; } - - rt_rndis_eth_t info = RT_NULL; - - info = (rt_rndis_eth_t)rndis_class->user_data; - - ret = usbh_rndis_bulk_in_transfer(rndis_class, buffer, nbytes, 3); - rt_mutex_take(usbh_rndis_eth_device.rndis_mutex, RT_WAITING_FOREVER); - if (info->keepalive_timer) { - rt_timer_start(info->keepalive_timer); - } - rt_mutex_release(usbh_rndis_eth_device.rndis_mutex); + ret = usbh_rndis_bulk_in_transfer(rndis_class->rndis_class, buffer, nbytes, RT_WAITING_FOREVER); return ret; } @@ -191,9 +179,9 @@ static rt_err_t rndis_msg_data_recv(struct usbh_rndis *rndis_class, rt_uint8_t * * * @return the error code, RT_EOK on successfully. */ -static rt_err_t rt_rndis_keepalive_msg(struct usbh_rndis *rndis_class) +static rt_err_t rt_rndis_keepalive_msg(struct usbh_user_rndis *rndis_class) { - return usbh_rndis_keepalive(rndis_class); + return usbh_rndis_keepalive(rndis_class->rndis_class); } /** @@ -209,108 +197,70 @@ static rt_err_t rt_rndis_keepalive_msg(struct usbh_rndis *rndis_class) void rt_usbh_rndis_data_recv_entry(void *pdata) { int ret = 0; - struct usbh_rndis *rndis_class = (struct usbh_rndis *)pdata; + struct usbh_user_rndis *rndis_class = (struct usbh_user_rndis *)pdata; rt_rndis_eth_t device = RT_NULL; - rndis_packet_msg_t pmsg = RT_NULL; device = (rt_rndis_eth_t)rndis_class->user_data; + err_t err; + struct pbuf *p; + rndis_data_packet_t *pmsg; + int pmg_offset; + int payload_offset; if ((pdata == RT_NULL) || (rndis_class == RT_NULL) || (device == RT_NULL)) { return; } - while (1) { - ret = rndis_msg_data_recv(rndis_class, device->rx_buf_ptr, RNDIS_ETH_BUFFER_LEN); - if (ret > 0) { - pmsg = (rndis_packet_msg_t)device->rx_buf_ptr; + device->rx_buf_ptr = device->rx_buffer; - if (device->frame_debug == RT_TRUE) { - hex_data_print("rndis eth rx", device->rx_buf_ptr, ret); - } - if (device->rx_buf_ptr == device->rx_bufferA) { - if (device->rx_lengthA) { - RNDIS_DEV_PRINTF("Rndis deivce rx bufferA overwrite!\n"); - } - device->rx_lengthA = ret; - device->rx_buf_ptr = device->rx_bufferB; - } else { - if (device->rx_lengthB) { - RNDIS_DEV_PRINTF("Rndis deivce rx bufferB overwrite!\n"); + while (1) { + pmg_offset = 0; + payload_offset = 0; + ret = usbh_rndis_bulk_in_transfer(rndis_class->rndis_class, device->rx_buf_ptr, RNDIS_ETH_BUFFER_LEN, RT_WAITING_FOREVER); + if (ret <= 0) { + rt_thread_mdelay(1); + continue; + } + while (ret > 0) { + pmsg = (rndis_data_packet_t *)(device->rx_buf_ptr + pmg_offset); + if (pmsg->MessageType == REMOTE_NDIS_PACKET_MSG) { + /* allocate buffer */ + p = pbuf_alloc(PBUF_RAW, pmsg->DataLength, PBUF_POOL); + if (p != NULL) { + struct pbuf *q; + for (q = p; q != NULL; q = q->next) { + /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */ + memcpy(q->payload, ((uint8_t *)(&pmsg->DataOffset) + pmsg->DataOffset + payload_offset), q->len); + payload_offset += q->len; + } + /* entry point to the LwIP stack */ + /* notify to upper layer */ + if(device->parent.netif->input(p, device->parent.netif)!= ERR_OK ) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: Input error\n")); + pbuf_free(p); + p = NULL; + } + pmg_offset += pmsg->MessageLength; + ret -= pmsg->MessageLength; } - device->rx_lengthB = ret; - device->rx_buf_ptr = device->rx_bufferA; - } - - if ((pmsg->MessageType == REMOTE_NDIS_PACKET_MSG) && (pmsg->MessageLength == ret)) { - device->recv_packet_counter++; - eth_device_ready((struct eth_device *)device); - } else { - RNDIS_DEV_PRINTF("Rndis deivce recv data error!\n"); } } - - if (ret == 0) { - ret = 0; - rt_thread_mdelay(10); - } else { - ret -= 1; - device->recv_packet_counter += 0; - rt_thread_mdelay(10); - } } } -/** - * This function power off the rndis device and power up it again. - * - * @rndis_class intf the usb interface instance. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_rndis_dev_power(struct usbh_rndis *rndis_class, rt_uint32_t time) -{ - /*power off the rndis device*/ - // rt_usbh_hub_clear_port_feature(intf->device->parent_hub, intf->device->port, PORT_FEAT_POWER); - // if(time) - // { - // rt_thread_mdelay(time); - // /*power up the rndis device */ - // rt_usbh_hub_set_port_feature(intf->device->parent_hub, intf->device->port, PORT_FEAT_POWER); - // } - - return RT_EOK; -} - void rt_rndis_dev_keepalive_timeout(void *pdata) { - struct usbh_rndis *rndis_class = (struct usbh_rndis *)pdata; + struct usbh_user_rndis *rndis_class = (struct usbh_user_rndis *)pdata; static rt_uint32_t keepalive_error = 0; if (rndis_class == RT_NULL) { return; } - rt_rndis_eth_t info = RT_NULL; - - info = (rt_rndis_eth_t)rndis_class->user_data; - - if (RT_EOK == rt_rndis_keepalive_msg(rndis_class)) { - RNDIS_DEV_PRINTF("rndis dev keepalive success!\n"); - keepalive_error = 0; - rt_mutex_take(usbh_rndis_eth_device.rndis_mutex, RT_WAITING_FOREVER); - if (info->keepalive_timer) { - rt_timer_start(info->keepalive_timer); - } - rt_mutex_release(usbh_rndis_eth_device.rndis_mutex); - } else { - keepalive_error++; - RNDIS_DEV_PRINTF("rndis dev keepalive timeout!\n"); - if (keepalive_error > 3) { - keepalive_error = 0; - rt_rndis_dev_power(rndis_class, RNDIS_DEV_POWER_OFF_TIME); - info->rndis_state = RNDIS_BUS_INITIALIZED; - } - } + rt_mutex_take(usbh_rndis_eth_device.rndis_mutex, RT_WAITING_FOREVER); + rt_rndis_keepalive_msg(rndis_class); + rt_mutex_release(usbh_rndis_eth_device.rndis_mutex); } /** @@ -320,7 +270,7 @@ void rt_rndis_dev_keepalive_timeout(void *pdata) * * @return the error code, RT_EOK on successfully. */ -rt_err_t rt_rndis_run(struct usbh_rndis *rndis_class, struct rndis_dev_info *dev_info) +rt_err_t rt_rndis_run(struct usbh_user_rndis *rndis_class) { rt_err_t ret = 0; // urndis_t rndis = RT_NULL; @@ -344,20 +294,20 @@ rt_err_t rt_rndis_run(struct usbh_rndis *rndis_class, struct rndis_dev_info *dev usbh_rndis_eth_device.keepalive_timer = rt_timer_create("keeplive", rt_rndis_dev_keepalive_timeout, rndis_class, RT_TICK_PER_SECOND * RNDIS_DEV_KEEPALIVE_TIMEOUT / 1000, - RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); + RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER); if (usbh_rndis_eth_device.keepalive_timer == RT_NULL) { ret = -RT_ENOMEM; goto __exit; } - + rt_timer_start(usbh_rndis_eth_device.keepalive_timer); rndis_class->user_data = (struct rt_device *)&usbh_rndis_eth_device; usbh_rndis_eth_device.rndis_recv = rt_thread_create("rndis", (void (*)(void *parameter))rt_usbh_rndis_data_recv_entry, rndis_class, 1024 + 512, - 15, + 5, 20); if (usbh_rndis_eth_device.rndis_recv == RT_NULL) { @@ -366,12 +316,12 @@ rt_err_t rt_rndis_run(struct usbh_rndis *rndis_class, struct rndis_dev_info *dev } /*the LINK SPEED is 100Mbps*/ - usbh_rndis_eth_device.rndis_speed = dev_info->rndis_speed; + usbh_rndis_eth_device.rndis_speed = rndis_class->rndis_class->link_speed; - eth_device_linkchange(&usbh_rndis_eth_device.parent, dev_info->up); + eth_device_linkchange(&usbh_rndis_eth_device.parent, rndis_class->rndis_class->link_status); for (j = 0; j < MAX_ADDR_LEN; j++) { - usbh_rndis_eth_device.dev_addr[j] = dev_info->dev_addr[j]; + usbh_rndis_eth_device.dev_addr[j] = rndis_class->rndis_class->mac[j]; } /* update the mac addr to netif interface */ @@ -397,14 +347,23 @@ __exit: } else { RNDIS_DEV_PRINTF("rndis dev faile!\n"); - /*rndis device run error, power off the device, try it agin*/ - rt_rndis_dev_power(rndis_class, RNDIS_DEV_POWER_OFF_TIME); } return ret; } -rt_err_t rt_rndis_stop(struct usbh_rndis *rndis_class) +void usbh_rndis_run(struct usbh_rndis *rndis_class) +{ + g_user_rndis = usb_malloc(sizeof(struct usbh_user_rndis)); + RT_ASSERT(g_user_rndis != RT_NULL); + g_user_rndis->rndis_class = rndis_class; + if (rt_rndis_run(g_user_rndis) == RT_EOK) { + eth_device_init(&usbh_rndis_eth_device.parent, RNDIS_NET_DEV_NAME); + eth_device_linkchange(&usbh_rndis_eth_device.parent, RT_FALSE); + } +} + +rt_err_t rt_rndis_stop(struct usbh_user_rndis *rndis_class) { rt_rndis_eth_t info = RT_NULL; @@ -432,6 +391,12 @@ rt_err_t rt_rndis_stop(struct usbh_rndis *rndis_class) return RT_EOK; } +void usbh_rndis_stop(struct usbh_rndis *rndis_class) +{ + RT_ASSERT(g_user_rndis != RT_NULL); + rt_rndis_stop(g_user_rndis); + usb_free(g_user_rndis); +} /** * This function rndis eth device. * @@ -480,21 +445,6 @@ static rt_err_t rt_rndis_eth_control(rt_device_t dev, int cmd, void *args) } break; - case NIOTCTL_GTXCOUNTER: - if (args) { - *(rt_uint32_t *)args = rndis_eth_dev->send_packet_counter; - } else { - return -RT_ERROR; - } - break; - - case NIOTCTL_GRXCOUNTER: - if (args) { - *(rt_uint32_t *)args = rndis_eth_dev->recv_packet_counter; - } else { - return -RT_ERROR; - } - break; default: break; } @@ -504,52 +454,12 @@ static rt_err_t rt_rndis_eth_control(rt_device_t dev, int cmd, void *args) /* ethernet device interface */ -/* reception packet. */ -struct pbuf *rt_rndis_eth_rx(rt_device_t dev) -{ - struct pbuf *p = RT_NULL; - rt_uint32_t offset = 0; - rt_rndis_eth_t device = (rt_rndis_eth_t)dev; - rt_uint32_t recv_len = 0; - - rndis_packet_msg_t pmsg = RT_NULL; - - if (device->rx_buf_ptr == device->rx_bufferA) { - pmsg = (rndis_packet_msg_t)device->rx_bufferB; - recv_len = device->rx_lengthB; - } else { - pmsg = (rndis_packet_msg_t)device->rx_bufferA; - recv_len = device->rx_lengthA; - } - - if ((recv_len == 0) || (pmsg->DataLength == 0)) { - return RT_NULL; - } - - /* allocate buffer */ - p = pbuf_alloc(PBUF_LINK, pmsg->DataLength, PBUF_RAM); - if (p != RT_NULL) { - struct pbuf *q; - - for (q = p; q != RT_NULL; q = q->next) { - /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */ - rt_memcpy(q->payload, - (rt_uint8_t *)((pmsg->data) + offset), - q->len); - offset += q->len; - } - } - - if (device->rx_buf_ptr == device->rx_bufferA) { - device->rx_lengthB = 0; - } else { - device->rx_lengthA = 0; - } - - return p; -} /* transmit packet. */ +extern int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, + uint32_t oid, uint32_t query_len, + uint8_t *info, uint32_t *info_len); + rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf *p) { struct pbuf *q; @@ -557,9 +467,36 @@ rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf *p) rt_err_t result = RT_EOK; rt_rndis_eth_t device = (rt_rndis_eth_t)dev; rndis_packet_msg_t msg = RT_NULL; + int recount = 5; + int ret; + uint8_t data[4]; + uint32_t info_len = 0; if (!device->parent.link_status) { + while (RT_TRUE) { + if (device->rndis_class == RT_NULL) { + rt_thread_delay(1000); + continue; + } + break; + } RNDIS_DEV_PRINTF("linkdown, drop pkg\r\n"); + while(recount--) { + ret = usbh_rndis_query_msg_transfer(device->rndis_class->rndis_class, OID_GEN_MEDIA_CONNECT_STATUS, sizeof(data), data, &info_len); + if (ret < 0) { + return -EBUSY; + } + if (NDIS_MEDIA_STATE_CONNECTED == data[0]) { + device->rndis_class->rndis_class->link_status = true; + eth_device_linkchange(&usbh_rndis_eth_device.parent, RT_TRUE); + RNDIS_DEV_PRINTF("linkup, drop pkg\r\n"); + break; + } else { + device->rndis_class->rndis_class->link_status = false; + eth_device_linkchange(&usbh_rndis_eth_device.parent, RT_FALSE); + } + rt_thread_delay(100); + } return RT_EOK; } @@ -616,6 +553,11 @@ const static struct rt_device_ops rndis_device_ops = { #endif #endif +__WEAK void lowlevel_usb_init(void) +{ + +} + int usbh_rndis_eth_device_init(void) { /* OUI 00-00-00, only for test. */ @@ -645,21 +587,18 @@ int usbh_rndis_eth_device_init(void) #endif usbh_rndis_eth_device.parent.parent.user_data = RT_NULL; - usbh_rndis_eth_device.parent.eth_rx = rt_rndis_eth_rx; + usbh_rndis_eth_device.parent.eth_rx = RT_NULL; usbh_rndis_eth_device.parent.eth_tx = rt_rndis_eth_tx; /* register eth device */ - usbh_rndis_eth_device.rx_lengthA = 0; - usbh_rndis_eth_device.rx_lengthB = 0; - usbh_rndis_eth_device.rx_buf_ptr = usbh_rndis_eth_device.rx_bufferA; + usbh_rndis_eth_device.rx_buf_ptr = usbh_rndis_eth_device.rx_buffer; usbh_rndis_eth_device.frame_debug = RT_FALSE; usbh_rndis_eth_device.send_packet_counter = 0; usbh_rndis_eth_device.recv_packet_counter = 0; - eth_device_init(&usbh_rndis_eth_device.parent, RNDIS_NET_DEV_NAME); + lowlevel_usb_init(); - eth_device_linkchange(&usbh_rndis_eth_device.parent, RT_FALSE); return RT_EOK; } INIT_APP_EXPORT(usbh_rndis_eth_device_init); @@ -687,4 +626,4 @@ static void eth_rndis_frame_debug(int argc, char **argv) #ifdef FINSH_USING_MSH #include <finsh.h> MSH_CMD_EXPORT_ALIAS(eth_rndis_frame_debug, rndis_debug, set eth rndis frame print); -#endif /* FINSH_USING_MSH */
\ No newline at end of file +#endif /* FINSH_USING_MSH */ |
