diff --git a/cherryusb_config_template.h b/cherryusb_config_template.h index cba9fc4d..27f25199 100644 --- a/cherryusb_config_template.h +++ b/cherryusb_config_template.h @@ -168,6 +168,17 @@ #define CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE (2048) #endif +/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, + * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. + */ +#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE +#define CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE (2048) +#endif +/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ +#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE +#define CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE (2048) +#endif + /* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. */ diff --git a/class/cdc/usbh_cdc_ecm.c b/class/cdc/usbh_cdc_ecm.c index f7f9563f..e5ee046b 100644 --- a/class/cdc/usbh_cdc_ecm.c +++ b/class/cdc/usbh_cdc_ecm.c @@ -246,30 +246,33 @@ find_class: usb_osal_msleep(100); goto find_class; } + usb_osal_msleep(128); } g_cdc_ecm_rx_length = 0; while (1) { - usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkin_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkin, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_length], CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL); + usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkin_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkin, g_cdc_ecm_rx_buffer, CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL); ret = usbh_submit_urb(&g_cdc_ecm_class.bulkin_urb); if (ret < 0) { goto find_class; } - g_cdc_ecm_rx_length += g_cdc_ecm_class.bulkin_urb.actual_length; + g_cdc_ecm_rx_length = g_cdc_ecm_class.bulkin_urb.actual_length; - if (g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize)) { + /* A transfer is complete because last packet is a short packet. + * Short packet is not zero, match g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize). + * Short packet is zero, check if g_cdc_ecm_class.bulkin_urb.actual_length < transfer_size, for example transfer is complete with size is 512 < 1514. + * This case is always true + */ + if (g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize) || + (g_cdc_ecm_class.bulkin_urb.actual_length < CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE)) { USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_length); usbh_cdc_ecm_eth_input(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_length); g_cdc_ecm_rx_length = 0; } else { - /* read continue util read short packet */ - if (g_cdc_ecm_rx_length > CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE) { - USB_LOG_ERR("Rx packet is overflow\r\n"); - g_cdc_ecm_rx_length = 0; - } + /* There's no way to run here. */ } } // clang-format off diff --git a/class/cdc/usbh_cdc_ncm.c b/class/cdc/usbh_cdc_ncm.c index ac220f57..1162bb38 100644 --- a/class/cdc/usbh_cdc_ncm.c +++ b/class/cdc/usbh_cdc_ncm.c @@ -248,6 +248,11 @@ void usbh_cdc_ncm_rx_thread(void *argument) { uint32_t g_cdc_ncm_rx_length; int ret; +#if CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE <= (16 * 1024) + uint32_t transfer_size = CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE; +#else + uint32_t transfer_size = (16 * 1024); +#endif USB_LOG_INFO("Create cdc ncm rx thread\r\n"); // clang-format off @@ -268,7 +273,7 @@ find_class: g_cdc_ncm_rx_length = 0; while (1) { - usbh_bulk_urb_fill(&g_cdc_ncm_class.bulkin_urb, g_cdc_ncm_class.hport, g_cdc_ncm_class.bulkin, &g_cdc_ncm_rx_buffer[g_cdc_ncm_rx_length], (CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE > (16 * 1024)) ? (16 * 1024) : CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL); + usbh_bulk_urb_fill(&g_cdc_ncm_class.bulkin_urb, g_cdc_ncm_class.hport, g_cdc_ncm_class.bulkin, &g_cdc_ncm_rx_buffer[g_cdc_ncm_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL); ret = usbh_submit_urb(&g_cdc_ncm_class.bulkin_urb); if (ret < 0) { goto find_class; @@ -276,7 +281,12 @@ find_class: g_cdc_ncm_rx_length += g_cdc_ncm_class.bulkin_urb.actual_length; - if (g_cdc_ncm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ncm_class.bulkin->wMaxPacketSize)) { + /* A transfer is complete because last packet is a short packet. + * Short packet is not zero, match g_cdc_ncm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ncm_class.bulkin->wMaxPacketSize). + * Short packet is zero, check if g_cdc_ncm_class.bulkin_urb.actual_length < transfer_size, for example transfer is complete with size is 1024 < 2048. + */ + if ((g_cdc_ncm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ncm_class.bulkin->wMaxPacketSize)) || + (g_cdc_ncm_class.bulkin_urb.actual_length < transfer_size)) { USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ncm_rx_length); struct cdc_ncm_nth16 *nth16 = (struct cdc_ncm_nth16 *)&g_cdc_ncm_rx_buffer[0]; @@ -309,11 +319,15 @@ find_class: } g_cdc_ncm_rx_length = 0; - } else { - if (g_cdc_ncm_rx_length > CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE) { - USB_LOG_ERR("Rx packet is overflow\r\n"); - g_cdc_ncm_rx_length = 0; +#if CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE <= (16 * 1024) + if (g_cdc_ncm_rx_length == CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE) { +#else + if ((g_cdc_ncm_rx_length + (16 * 1024)) > CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE) { +#endif + USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE\r\n"); + while (1) { + } } } } diff --git a/class/vendor/net/usbh_asix.c b/class/vendor/net/usbh_asix.c index 111277a7..b7010153 100644 --- a/class/vendor/net/usbh_asix.c +++ b/class/vendor/net/usbh_asix.c @@ -14,10 +14,9 @@ #define DEV_FORMAT "/dev/asix" static struct usbh_asix g_asix_class; -#define CONFIG_USBHOST_ASIX_ETH_MAX_SIZE (1514U + 8) -static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_rx_buffer[CONFIG_USBHOST_ASIX_ETH_MAX_SIZE]; -static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_tx_buffer[CONFIG_USBHOST_ASIX_ETH_MAX_SIZE]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_rx_buffer[CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_tx_buffer[CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE]; static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_inttx_buffer[16]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_asix_buf[32]; @@ -263,6 +262,15 @@ static int usbh_asix_write_gpio(struct usbh_asix *asix_class, uint16_t value, in static void usbh_asix_set_multicast(struct usbh_asix *asix_class) { uint16_t rx_ctl = AX_DEFAULT_RX_CTL | AX_RX_CTL_AM; +#if CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE == 4096 + rx_ctl |= AX_RX_CTL_MFB_4096; +#elif CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE == 8192 + rx_ctl |= AX_RX_CTL_MFB_8192; +#elif CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE == 16384 + rx_ctl |= AX_RX_CTL_MFB_16384; +#else + rx_ctl |= AX_RX_CTL_MFB_2048; +#endif const uint8_t multi_filter[] = { 0x00, 0x00, 0x20, 0x80, 0x00, 0x00, 0x00, 0x40 }; usbh_asix_write_cmd(asix_class, AX_CMD_WRITE_MULTI_FILTER, 0, 0, (uint8_t *)multi_filter, AX_MCAST_FILTER_SIZE); @@ -655,6 +663,12 @@ void usbh_asix_rx_thread(void *argument) int ret; uint16_t len; uint16_t len_crc; + uint32_t data_offset; +#if CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE <= (16 * 1024) + uint32_t transfer_size = CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE; +#else + uint32_t transfer_size = (16 * 1024); +#endif USB_LOG_INFO("Create asix rx thread\r\n"); // clang-format off @@ -671,11 +685,12 @@ find_class: usb_osal_msleep(100); goto find_class; } + usb_osal_msleep(128); } g_asix_rx_length = 0; while (1) { - usbh_bulk_urb_fill(&g_asix_class.bulkin_urb, g_asix_class.hport, g_asix_class.bulkin, &g_asix_rx_buffer[g_asix_rx_length], CONFIG_USBHOST_ASIX_ETH_MAX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL); + usbh_bulk_urb_fill(&g_asix_class.bulkin_urb, g_asix_class.hport, g_asix_class.bulkin, &g_asix_rx_buffer[g_asix_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL); ret = usbh_submit_urb(&g_asix_class.bulkin_urb); if (ret < 0) { goto find_class; @@ -683,24 +698,39 @@ find_class: g_asix_rx_length += g_asix_class.bulkin_urb.actual_length; - if (g_asix_rx_length % USB_GET_MAXPACKETSIZE(g_asix_class.bulkin->wMaxPacketSize)) { - len = ((uint16_t)g_asix_rx_buffer[0] | ((uint16_t)(g_asix_rx_buffer[1]) << 8)) & 0x7ff; - len_crc = g_asix_rx_buffer[2] | ((uint16_t)(g_asix_rx_buffer[3]) << 8); - - if (len != (~len_crc & 0x7ff)) { - USB_LOG_ERR("asix rx header error\r\n"); - continue; - } - + /* A transfer is complete because last packet is a short packet. + * Short packet is not zero, match g_asix_rx_length % USB_GET_MAXPACKETSIZE(g_asix_class.bulkin->wMaxPacketSize). + * Short packet is zero, check if g_asix_class.bulkin_urb.actual_length < transfer_size, for example transfer is complete with size is 1024 < 2048. + */ + if (g_asix_rx_length % USB_GET_MAXPACKETSIZE(g_asix_class.bulkin->wMaxPacketSize) || + (g_asix_class.bulkin_urb.actual_length < transfer_size)) { USB_LOG_DBG("rxlen:%d\r\n", g_asix_rx_length); - uint8_t *buf = (uint8_t *)&g_asix_rx_buffer[4]; - usbh_asix_eth_input(buf, len); - g_asix_rx_length = 0; + data_offset = 0; + while (g_asix_rx_length > 0) { + len = ((uint16_t)g_asix_rx_buffer[data_offset + 0] | ((uint16_t)(g_asix_rx_buffer[data_offset + 1]) << 8)) & 0x7ff; + len_crc = g_asix_rx_buffer[data_offset + 2] | ((uint16_t)(g_asix_rx_buffer[data_offset + 3]) << 8); + + if (len != (~len_crc & 0x7ff)) { + USB_LOG_ERR("rx header error\r\n"); + g_asix_rx_length = 0; + continue; + } + + uint8_t *buf = (uint8_t *)&g_asix_rx_buffer[data_offset + 4]; + usbh_asix_eth_input(buf, len); + g_asix_rx_length -= (len + 4); + data_offset += (len + 4); + } } else { - if (g_asix_rx_length > CONFIG_USBHOST_ASIX_ETH_MAX_SIZE) { - USB_LOG_ERR("Rx packet is overflow\r\n"); - g_asix_rx_length = 0; +#if CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE <= (16 * 1024) + if (g_asix_rx_length == CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE) { +#else + if ((g_asix_rx_length + (16 * 1024)) > CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE) { +#endif + USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE\r\n"); + while (1) { + } } } } diff --git a/class/vendor/net/usbh_rtl8152.c b/class/vendor/net/usbh_rtl8152.c index df152744..2cdadcc3 100644 --- a/class/vendor/net/usbh_rtl8152.c +++ b/class/vendor/net/usbh_rtl8152.c @@ -2124,6 +2124,11 @@ void usbh_rtl8152_rx_thread(void *argument) int ret; uint16_t len; uint16_t data_offset; +#if CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE <= (16 * 1024) + uint32_t transfer_size = CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE; +#else + uint32_t transfer_size = (16 * 1024); +#endif USB_LOG_INFO("Create rtl8152 rx thread\r\n"); // clang-format off @@ -2154,7 +2159,7 @@ find_class: g_rtl8152_rx_length = 0; while (1) { - usbh_bulk_urb_fill(&g_rtl8152_class.bulkin_urb, g_rtl8152_class.hport, g_rtl8152_class.bulkin, &g_rtl8152_rx_buffer[g_rtl8152_rx_length], (CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE > (16 * 1024)) ? (16 * 1024) : CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL); + usbh_bulk_urb_fill(&g_rtl8152_class.bulkin_urb, g_rtl8152_class.hport, g_rtl8152_class.bulkin, &g_rtl8152_rx_buffer[g_rtl8152_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL); ret = usbh_submit_urb(&g_rtl8152_class.bulkin_urb); if (ret < 0) { goto find_class; @@ -2162,7 +2167,12 @@ find_class: g_rtl8152_rx_length += g_rtl8152_class.bulkin_urb.actual_length; - if (g_rtl8152_rx_length % USB_GET_MAXPACKETSIZE(g_rtl8152_class.bulkin->wMaxPacketSize)) { + /* A transfer is complete because last packet is a short packet. + * Short packet is not zero, match g_rtl8152_rx_length % USB_GET_MAXPACKETSIZE(g_rtl8152_class.bulkin->wMaxPacketSize). + * Short packet is zero, check if g_rtl8152_class.bulkin_urb.actual_length < transfer_size, for example transfer is complete with size is 1024 < 2048. + */ + if (g_rtl8152_rx_length % USB_GET_MAXPACKETSIZE(g_rtl8152_class.bulkin->wMaxPacketSize) || + (g_rtl8152_class.bulkin_urb.actual_length < transfer_size)) { data_offset = 0; USB_LOG_DBG("rxlen:%d\r\n", g_rtl8152_rx_length); @@ -2185,9 +2195,14 @@ find_class: } } } else { - if (g_rtl8152_rx_length > CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE) { - USB_LOG_ERR("Rx packet is overflow\r\n"); - g_rtl8152_rx_length = 0; +#if CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE <= (16 * 1024) + if (g_rtl8152_rx_length == CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE) { +#else + if ((g_rtl8152_rx_length + (16 * 1024)) > CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE) { +#endif + USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE\r\n"); + while (1) { + } } } } diff --git a/class/wireless/usbh_rndis.c b/class/wireless/usbh_rndis.c index 369772eb..fc93be8a 100644 --- a/class/wireless/usbh_rndis.c +++ b/class/wireless/usbh_rndis.c @@ -434,6 +434,11 @@ void usbh_rndis_rx_thread(void *argument) uint32_t pmg_offset; rndis_data_packet_t *pmsg; rndis_data_packet_t temp; +#if CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE <= (16 * 1024) + uint32_t transfer_size = CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE; +#else + uint32_t transfer_size = (16 * 1024); +#endif USB_LOG_INFO("Create rndis rx thread\r\n"); // clang-format off @@ -450,17 +455,23 @@ find_class: usb_osal_msleep(100); goto find_class; } + usb_osal_msleep(128); } g_rndis_rx_length = 0; while (1) { - usbh_bulk_urb_fill(&g_rndis_class.bulkin_urb, g_rndis_class.hport, g_rndis_class.bulkin, g_rndis_rx_buffer, (CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE > (16 * 1024)) ? (16 * 1024) : CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL); + usbh_bulk_urb_fill(&g_rndis_class.bulkin_urb, g_rndis_class.hport, g_rndis_class.bulkin, &g_rndis_rx_buffer[g_rndis_rx_length], transfer_size, USB_OSAL_WAITING_FOREVER, NULL, NULL); ret = usbh_submit_urb(&g_rndis_class.bulkin_urb); if (ret < 0) { goto find_class; } g_rndis_rx_length += g_rndis_class.bulkin_urb.actual_length; + + /* A transfer is complete because last packet is a short packet. + * Short packet is not zero, match g_rndis_rx_length % USB_GET_MAXPACKETSIZE(g_rndis_class.bulkin->wMaxPacketSize). + * Short packet cannot be zero. + */ if (g_rndis_rx_length % USB_GET_MAXPACKETSIZE(g_rndis_class.bulkin->wMaxPacketSize)) { pmg_offset = 0; @@ -495,9 +506,14 @@ find_class: } } } else { - if (g_rndis_rx_length > CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE) { - USB_LOG_ERR("Rx packet is overflow\r\n"); - g_rndis_rx_length = 0; +#if CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE <= (16 * 1024) + if (g_rndis_rx_length == CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE) { +#else + if ((g_rndis_rx_length + (16 * 1024)) > CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE) { +#endif + USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE\r\n"); + while (1) { + } } } }