summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2022-10-06 22:30:46 +0800
committersakumisu <[email protected]>2022-10-06 22:55:23 +0800
commit36de428845aca4de0003d589565d58c0d63a4786 (patch)
tree5f0a0fdb20f5980fc0370665c861510f59b9f085
parent0541183aec26dac1ce40121d16729c775f484324 (diff)
update rndis device driver and template
-rw-r--r--cherryusb_config_template.h6
-rw-r--r--class/cdc/usb_cdc.h140
-rw-r--r--class/wireless/ndis.h7
-rw-r--r--class/wireless/usbd_rndis.c256
-rw-r--r--class/wireless/usbd_rndis.h18
-rw-r--r--demo/cdc_rndis_template.c174
6 files changed, 521 insertions, 80 deletions
diff --git a/cherryusb_config_template.h b/cherryusb_config_template.h
index 513fccc5..0b30f64b 100644
--- a/cherryusb_config_template.h
+++ b/cherryusb_config_template.h
@@ -93,6 +93,8 @@
#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB"
#endif
+#define CONFIG_USBDEV_RNDIS_USING_LWIP
+
/* ================ USB HOST Stack Configuration ================== */
#define CONFIG_USBHOST_MAX_RHPORTS 1
@@ -136,8 +138,8 @@
/* ================ EHCI Configuration ================ */
-#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
-#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
+#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
+#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
// #define CONFIG_USB_EHCI_INFO_ENABLE
// #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
diff --git a/class/cdc/usb_cdc.h b/class/cdc/usb_cdc.h
index 1dbca765..ed8184eb 100644
--- a/class/cdc/usb_cdc.h
+++ b/class/cdc/usb_cdc.h
@@ -344,8 +344,8 @@ struct cdc_ecm_descriptor {
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
int_ep, /* bEndpointAddress */ \
0x03, /* bmAttributes */ \
- 0x40, 0x00, /* wMaxPacketSize */ \
- 0x00, /* bInterval */ \
+ 0x08, 0x00, /* wMaxPacketSize */ \
+ 0x0a, /* bInterval */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
@@ -409,8 +409,144 @@ struct cdc_ecm_descriptor {
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
int_ep, /* bEndpointAddress */ \
0x03, /* bmAttributes */ \
+ 0x08, 0x00, /* wMaxPacketSize */ \
+ 0x10, /* bInterval */ \
+ 0x09, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
+ (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
+ 0x00, /* bAlternateSetting */ \
+ 0x02, /* bNumEndpoints */ \
+ CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \
+ 0x00, /* bInterfaceSubClass */ \
+ 0x00, /* bInterfaceProtocol */ \
+ 0x00, /* iInterface */ \
+ 0x07, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
+ out_ep, /* bEndpointAddress */ \
+ 0x02, /* bmAttributes */ \
0x00, 0x02, /* wMaxPacketSize */ \
0x00, /* bInterval */ \
+ 0x07, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
+ in_ep, /* bEndpointAddress */ \
+ 0x02, /* bmAttributes */ \
+ 0x00, 0x02, /* wMaxPacketSize */ \
+ 0x00 /* bInterval */
+#endif
+// clang-format on
+
+/*Length of template descriptor: 66 bytes*/
+#define CDC_RNDIS_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 4 + 5 + 7 + 9 + 7 + 7)
+// clang-format off
+#ifndef CONFIG_USB_HS
+#define CDC_RNDIS_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, str_idx) \
+ /* Interface Associate */ \
+ 0x08, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
+ bFirstInterface, /* bFirstInterface */ \
+ 0x02, /* bInterfaceCount */ \
+ USB_DEVICE_CLASS_WIRELESS, /* bFunctionClass */ \
+ CDC_DIRECT_LINE_CONTROL_MODEL, /* bFunctionSubClass */ \
+ CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bFunctionProtocol */ \
+ 0x00, /* iFunction */ \
+ 0x09, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
+ bFirstInterface, /* bInterfaceNumber */ \
+ 0x00, /* bAlternateSetting */ \
+ 0x01, /* bNumEndpoints */ \
+ USB_DEVICE_CLASS_WIRELESS, /* bInterfaceClass */ \
+ CDC_DIRECT_LINE_CONTROL_MODEL, /* bInterfaceSubClass */ \
+ CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bInterfaceProtocol */ \
+ str_idx, /* iInterface */ \
+ 0x05, /* bLength */ \
+ CDC_CS_INTERFACE, /* bDescriptorType */ \
+ CDC_FUNC_DESC_HEADER, /* bDescriptorSubtype */ \
+ WBVAL(CDC_V1_10), /* bcdCDC */ \
+ 0x05, /* bLength */ \
+ CDC_CS_INTERFACE, /* bDescriptorType */ \
+ CDC_FUNC_DESC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \
+ 0x00, /* bmCapabilities */ \
+ (uint8_t)(bFirstInterface + 1), /* bDataInterface */ \
+ 0x04, /* bLength */ \
+ CDC_CS_INTERFACE, /* bDescriptorType */ \
+ CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \
+ 0x00, /* bmCapabilities */ \
+ 0x05, /* bLength */ \
+ CDC_CS_INTERFACE, /* bDescriptorType */ \
+ CDC_FUNC_DESC_UNION, /* bDescriptorSubtype */ \
+ bFirstInterface, /* bMasterInterface */ \
+ (uint8_t)(bFirstInterface + 1), /* bSlaveInterface0 */ \
+ 0x07, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
+ int_ep, /* bEndpointAddress */ \
+ 0x03, /* bmAttributes */ \
+ 0x08, 0x00, /* wMaxPacketSize */ \
+ 0x10, /* bInterval */ \
+ 0x09, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
+ (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
+ 0x00, /* bAlternateSetting */ \
+ 0x02, /* bNumEndpoints */ \
+ CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \
+ 0x00, /* bInterfaceSubClass */ \
+ 0x00, /* bInterfaceProtocol */ \
+ 0x00, /* iInterface */ \
+ 0x07, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
+ out_ep, /* bEndpointAddress */ \
+ 0x02, /* bmAttributes */ \
+ 0x40, 0x00, /* wMaxPacketSize */ \
+ 0x00, /* bInterval */ \
+ 0x07, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
+ in_ep, /* bEndpointAddress */ \
+ 0x02, /* bmAttributes */ \
+ 0x40, 0x00, /* wMaxPacketSize */ \
+ 0x00 /* bInterval */
+#else
+#define CDC_RNDIS_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, str_idx) \
+ /* Interface Associate */ \
+ 0x08, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
+ bFirstInterface, /* bFirstInterface */ \
+ 0x02, /* bInterfaceCount */ \
+ USB_DEVICE_CLASS_WIRELESS, /* bFunctionClass */ \
+ CDC_DIRECT_LINE_CONTROL_MODEL, /* bFunctionSubClass */ \
+ CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bFunctionProtocol */ \
+ 0x00, /* iFunction */ \
+ 0x09, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
+ bFirstInterface, /* bInterfaceNumber */ \
+ 0x00, /* bAlternateSetting */ \
+ 0x01, /* bNumEndpoints */ \
+ USB_DEVICE_CLASS_WIRELESS, /* bInterfaceClass */ \
+ CDC_DIRECT_LINE_CONTROL_MODEL, /* bInterfaceSubClass */ \
+ CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bInterfaceProtocol */ \
+ str_idx, /* iInterface */ \
+ 0x05, /* bLength */ \
+ CDC_CS_INTERFACE, /* bDescriptorType */ \
+ CDC_FUNC_DESC_HEADER, /* bDescriptorSubtype */ \
+ WBVAL(CDC_V1_10), /* bcdCDC */ \
+ 0x05, /* bLength */ \
+ CDC_CS_INTERFACE, /* bDescriptorType */ \
+ CDC_FUNC_DESC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \
+ 0x00, /* bmCapabilities */ \
+ (uint8_t)(bFirstInterface + 1), /* bDataInterface */ \
+ 0x04, /* bLength */ \
+ CDC_CS_INTERFACE, /* bDescriptorType */ \
+ CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \
+ 0x00, /* bmCapabilities */ \
+ 0x05, /* bLength */ \
+ CDC_CS_INTERFACE, /* bDescriptorType */ \
+ CDC_FUNC_DESC_UNION, /* bDescriptorSubtype */ \
+ bFirstInterface, /* bMasterInterface */ \
+ (uint8_t)(bFirstInterface + 1), /* bSlaveInterface0 */ \
+ 0x07, /* bLength */ \
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
+ int_ep, /* bEndpointAddress */ \
+ 0x03, /* bmAttributes */ \
+ 0x08, 0x00, /* wMaxPacketSize */ \
+ 0x10, /* bInterval */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
diff --git a/class/wireless/ndis.h b/class/wireless/ndis.h
index 80682ff3..80a6e669 100644
--- a/class/wireless/ndis.h
+++ b/class/wireless/ndis.h
@@ -258,6 +258,13 @@ struct NDIS_PM_PACKET_PATTERN {
#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040
#define NDIS_MAC_OPTION_RESERVED 0x80000000
+/** Hardware status of the underlying NIC */
+#define NDIS_HW_STS_READY 0x00000000UL
+#define NDIS_HW_STS_INITIALIZING 0x00000001UL
+#define NDIS_HW_STS_RESET 0x00000002UL
+#define NDIS_HW_STS_CLOSING 0x00000003UL
+#define NDIS_HW_STS_NOT_READY 0x00000004UL
+
#endif /* _LINUX_NDIS_H */
/** @} */
diff --git a/class/wireless/usbd_rndis.c b/class/wireless/usbd_rndis.c
index 23535520..d234c7ed 100644
--- a/class/wireless/usbd_rndis.c
+++ b/class/wireless/usbd_rndis.c
@@ -7,33 +7,56 @@
#include "usbd_rndis.h"
#include "rndis_protocol.h"
+#define RNDIS_OUT_EP_IDX 0
+#define RNDIS_IN_EP_IDX 1
+#define RNDIS_INT_EP_IDX 2
+
+/* Describe EndPoints configuration */
+static struct usbd_endpoint rndis_ep_data[3];
+
#define RNDIS_INQUIRY_PUT(src, len) (memcpy(infomation_buffer, src, len))
#define RNDIS_INQUIRY_PUT_LE32(value) (*(uint32_t *)infomation_buffer = (value))
+#ifdef CONFIG_USB_HS
+#define RNDIS_MAX_PACKET_SIZE 512
+#else
+#define RNDIS_MAX_PACKET_SIZE 512
+#endif
+
+#ifndef CONFIG_USB_HS
+#define RNDIS_LINK_SPEED 12000000 /* Link baudrate (12Mbit/s for USB-FS) */
+#else
+#define RNDIS_LINK_SPEED 480000000 /* Link baudrate (480Mbit/s for USB-HS) */
+#endif
+
/* Device data structure */
struct usbd_rndis_cfg_priv {
uint32_t drv_version;
- uint32_t media_status;
+ uint32_t link_status;
uint32_t speed;
- uint32_t mtu;
uint32_t net_filter;
usb_eth_stat_t eth_state;
rndis_state_t init_state;
- uint8_t int_ep;
uint8_t mac[6];
- uint32_t vendor_id;
- uint8_t *vendor_desc;
} usbd_rndis_cfg = { .drv_version = 0x0001,
- .media_status = NDIS_MEDIA_STATE_DISCONNECTED,
- .mtu = CONFIG_USBDEV_RNDIS_MTU,
+ .link_status = NDIS_MEDIA_STATE_DISCONNECTED,
.speed = RNDIS_LINK_SPEED,
.init_state = rndis_uninitialized,
- .mac = { 0x00, 0x00, 0x5E, 0x00, 0x53, 0x01 },
- .vendor_id = 0xffffffff,
- .vendor_desc = "CherryUSB" };
+ .mac = { 0x00, 0x00, 0x5E, 0x00, 0x53, 0x01 } };
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44];
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t rndis_encapsulated_resp_buffer[CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t NOTIFY_RESPONSE_AVAILABLE[8] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+volatile uint8_t *g_rndis_rx_data_buffer;
+volatile uint32_t g_rndis_rx_data_length;
+volatile uint32_t g_rndis_tx_data_length;
/* RNDIS options list */
const uint32_t oid_supported_list[] = {
+ /* General OIDs */
OID_GEN_SUPPORTED_LIST,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_SUPPORTED,
@@ -47,32 +70,46 @@ const uint32_t oid_supported_list[] = {
OID_GEN_VENDOR_DRIVER_VERSION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_MAXIMUM_TOTAL_SIZE,
- OID_GEN_PROTOCOL_OPTIONS,
- OID_GEN_MAC_OPTIONS,
OID_GEN_MEDIA_CONNECT_STATUS,
- OID_GEN_MAXIMUM_SEND_PACKETS,
+
+ OID_GEN_PHYSICAL_MEDIUM,
+
+ /* General Statistic OIDs */
+ OID_GEN_XMIT_OK,
+ OID_GEN_RCV_OK,
+ OID_GEN_XMIT_ERROR,
+ OID_GEN_RCV_ERROR,
+ OID_GEN_RCV_NO_BUFFER,
+
+ /* Please configure us */
+ OID_GEN_RNDIS_CONFIG_PARAMETER,
+
+ /* 802.3 OIDs */
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAXIMUM_LIST_SIZE,
- OID_802_3_MAC_OPTIONS
-};
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t rndis_encapsulated_resp_buffer[CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE];
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t NOTIFY_RESPONSE_AVAILABLE[8] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ /* 802.3 Statistic OIDs */
+ OID_802_3_RCV_ERROR_ALIGNMENT,
+ OID_802_3_XMIT_ONE_COLLISION,
+ OID_802_3_XMIT_MORE_COLLISIONS,
+
+ OID_802_3_MAC_OPTIONS,
+};
static int rndis_encapsulated_cmd_handler(uint8_t *data, uint32_t len);
static void rndis_notify_rsp(void)
{
- usbd_ep_start_write(usbd_rndis_cfg.int_ep, NOTIFY_RESPONSE_AVAILABLE, 8);
+ usbd_ep_start_write(rndis_ep_data[RNDIS_INT_EP_IDX].ep_addr, NOTIFY_RESPONSE_AVAILABLE, 8);
}
static int rndis_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
{
switch (setup->bRequest) {
case CDC_REQUEST_SEND_ENCAPSULATED_COMMAND:
- rndis_encapsulated_cmd_handler(data, len);
+ rndis_encapsulated_cmd_handler(*data, setup->wLength);
break;
case CDC_REQUEST_GET_ENCAPSULATED_RESPONSE:
*data = rndis_encapsulated_resp_buffer;
@@ -82,6 +119,8 @@ static int rndis_class_interface_request_handler(struct usb_setup_packet *setup,
default:
return -1;
}
+
+ return 0;
}
static int rndis_init_cmd_handler(uint8_t *data, uint32_t len);
@@ -96,22 +135,16 @@ static int rndis_encapsulated_cmd_handler(uint8_t *data, uint32_t len)
switch (((rndis_generic_msg_t *)data)->MessageType) {
case REMOTE_NDIS_INITIALIZE_MSG:
return rndis_init_cmd_handler(data, len);
- break;
case REMOTE_NDIS_HALT_MSG:
return rndis_halt_cmd_handler(data, len);
- break;
case REMOTE_NDIS_QUERY_MSG:
return rndis_query_cmd_handler(data, len);
- break;
case REMOTE_NDIS_SET_MSG:
return rndis_set_cmd_handler(data, len);
- break;
case REMOTE_NDIS_RESET_MSG:
return rndis_reset_cmd_handler(data, len);
- break;
case REMOTE_NDIS_KEEPALIVE_MSG:
return rndis_keepalive_cmd_handler(data, len);
- break;
default:
break;
@@ -134,7 +167,7 @@ static int rndis_init_cmd_handler(uint8_t *data, uint32_t len)
resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
resp->Medium = RNDIS_MEDIUM_802_3;
resp->MaxPacketsPerTransfer = 1;
- resp->MaxTransferSize = usbd_rndis_cfg.mtu + ETH_HEADER_SIZE + sizeof(rndis_data_packet_t);
+ resp->MaxTransferSize = CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + sizeof(rndis_data_packet_t);
resp->PacketAlignmentFactor = 0;
resp->AfListOffset = 0;
resp->AfListSize = 0;
@@ -177,63 +210,56 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
RNDIS_INQUIRY_PUT(oid_supported_list, sizeof(oid_supported_list));
infomation_len = sizeof(oid_supported_list);
break;
- case OID_GEN_VENDOR_DRIVER_VERSION:
- RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.drv_version);
+ case OID_GEN_HARDWARE_STATUS:
+ RNDIS_INQUIRY_PUT_LE32(NDIS_HW_STS_READY);
infomation_len = 4;
break;
- case OID_802_3_CURRENT_ADDRESS:
- RNDIS_INQUIRY_PUT(usbd_rndis_cfg.mac, 6);
- infomation_len = 6;
- break;
- case OID_802_3_PERMANENT_ADDRESS:
- RNDIS_INQUIRY_PUT(usbd_rndis_cfg.mac, 6);
- infomation_len = 6;
- break;
case OID_GEN_MEDIA_SUPPORTED:
- RNDIS_INQUIRY_PUT_LE32(NDIS_MEDIUM_802_3);
- infomation_len = 4;
- break;
case OID_GEN_MEDIA_IN_USE:
RNDIS_INQUIRY_PUT_LE32(NDIS_MEDIUM_802_3);
infomation_len = 4;
break;
- case OID_GEN_PHYSICAL_MEDIUM:
- RNDIS_INQUIRY_PUT_LE32(NDIS_MEDIUM_802_3);
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ RNDIS_INQUIRY_PUT_LE32(CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE);
infomation_len = 4;
break;
- case OID_GEN_HARDWARE_STATUS:
- RNDIS_INQUIRY_PUT_LE32(0);
+ case OID_GEN_VENDOR_ID:
+ RNDIS_INQUIRY_PUT_LE32(CONFIG_USBDEV_RNDIS_VENDOR_ID);
infomation_len = 4;
break;
- case OID_GEN_LINK_SPEED:
- RNDIS_INQUIRY_PUT_LE32(RNDIS_LINK_SPEED / 100);
+ case OID_GEN_VENDOR_DRIVER_VERSION:
+ RNDIS_INQUIRY_PUT_LE32(0x0001);
infomation_len = 4;
break;
- case OID_GEN_VENDOR_ID:
- RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.vendor_id);
+ case OID_GEN_VENDOR_DESCRIPTION:
+ RNDIS_INQUIRY_PUT(CONFIG_USBDEV_RNDIS_VENDOR_DESC, strlen(CONFIG_USBDEV_RNDIS_VENDOR_DESC));
+ infomation_len = (strlen(CONFIG_USBDEV_RNDIS_VENDOR_DESC) + 1);
+ break;
+ case OID_802_3_CURRENT_ADDRESS:
+ case OID_802_3_PERMANENT_ADDRESS:
+ RNDIS_INQUIRY_PUT(usbd_rndis_cfg.mac, 6);
+ infomation_len = 6;
+ break;
+ case OID_GEN_PHYSICAL_MEDIUM:
+ RNDIS_INQUIRY_PUT_LE32(NDIS_MEDIUM_802_3);
infomation_len = 4;
break;
- case OID_GEN_VENDOR_DESCRIPTION:
- RNDIS_INQUIRY_PUT(usbd_rndis_cfg.vendor_desc, strlen(usbd_rndis_cfg.vendor_desc) + 1);
- infomation_len = (strlen(usbd_rndis_cfg.vendor_desc) + 1);
+ case OID_GEN_LINK_SPEED:
+ RNDIS_INQUIRY_PUT_LE32(RNDIS_LINK_SPEED / 100);
+ infomation_len = 4;
break;
case OID_GEN_CURRENT_PACKET_FILTER:
RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.net_filter);
infomation_len = 4;
break;
- case OID_GEN_MAXIMUM_FRAME_SIZE:
- RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.mtu);
- infomation_len = 4;
- break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
- case OID_GEN_TRANSMIT_BLOCK_SIZE:
- case OID_GEN_RECEIVE_BLOCK_SIZE:
- //RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.mtu + ETH_HEADER_SIZE + sizeof(rndis_data_packet_t));
- RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.mtu + ETH_HEADER_SIZE);
+ RNDIS_INQUIRY_PUT_LE32(CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE);
infomation_len = 4;
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
- RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.media_status);
+ RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.link_status);
infomation_len = 4;
break;
case OID_GEN_RNDIS_CONFIG_PARAMETER:
@@ -401,7 +427,13 @@ static void rndis_notify_handler(uint8_t event, void *arg)
{
switch (event) {
case USBD_EVENT_RESET:
-
+ usbd_rndis_cfg.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
+ break;
+ case USBD_EVENT_CONFIGURED:
+ g_rndis_rx_data_length = 0;
+ g_rndis_tx_data_length = 0;
+ usbd_rndis_cfg.link_status = NDIS_MEDIA_STATE_CONNECTED;
+ usbd_ep_start_read(rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
break;
default:
@@ -409,7 +441,95 @@ static void rndis_notify_handler(uint8_t event, void *arg)
}
}
-struct usbd_interface *usbd_rndis_alloc_intf(uint8_t int_ep, uint8_t mac[6], uint32_t vendor_id, uint8_t *vendor_desc)
+void rndis_bulk_out(uint8_t ep, uint32_t nbytes)
+{
+ rndis_data_packet_t *hdr;
+
+ hdr = (rndis_data_packet_t *)g_rndis_rx_buffer;
+ g_rndis_rx_data_buffer = g_rndis_rx_buffer;
+ if ((hdr->MessageType != NDIS_PACKET_TYPE_DIRECTED) || (nbytes != hdr->MessageLength)) {
+ usbd_ep_start_read(rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
+ return;
+ }
+
+ /* Point to the payload and update the message length */
+ g_rndis_rx_data_buffer += hdr->DataOffset + sizeof(rndis_generic_msg_t);
+ g_rndis_rx_data_length = hdr->DataLength;
+
+ usbd_rndis_data_recv((uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_data_length);
+}
+
+void rndis_bulk_in(uint8_t ep, uint32_t nbytes)
+{
+ if ((nbytes % RNDIS_MAX_PACKET_SIZE) == 0 && nbytes) {
+ /* send zlp */
+ usbd_ep_start_write(ep, NULL, 0);
+ } else {
+ g_rndis_tx_data_length = 0;
+ }
+}
+
+#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
+#include <lwip/pbuf.h>
+
+struct pbuf *usbd_rndis_eth_rx(void)
+{
+ struct pbuf *p;
+
+ if (g_rndis_rx_data_length == 0) {
+ return NULL;
+ }
+ p = pbuf_alloc(PBUF_RAW, g_rndis_rx_data_length, PBUF_POOL);
+ if (p == NULL) {
+ return NULL;
+ }
+ memcpy(p->payload, (uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_data_length);
+ p->len = g_rndis_rx_data_length;
+
+ g_rndis_rx_data_length = 0;
+ usbd_ep_start_read(rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
+
+ return p;
+}
+
+int usbd_rndis_eth_tx(struct pbuf *p)
+{
+ struct pbuf *q;
+ uint8_t *buffer;
+ rndis_data_packet_t *hdr;
+
+ if (usbd_rndis_cfg.link_status == NDIS_MEDIA_STATE_DISCONNECTED) {
+ return 0;
+ }
+
+ if (g_rndis_tx_data_length > 0) {
+ return -EBUSY;
+ }
+
+ if (p->tot_len > sizeof(g_rndis_tx_buffer)) {
+ p->tot_len = sizeof(g_rndis_tx_buffer);
+ }
+
+ buffer = (uint8_t *)(g_rndis_tx_buffer + sizeof(rndis_data_packet_t));
+ for (q = p; q != NULL; q = q->next) {
+ memcpy(buffer, q->payload, q->len);
+ buffer += q->len;
+ }
+
+ hdr = (rndis_data_packet_t *)g_rndis_tx_buffer;
+
+ memset(hdr, 0, sizeof(rndis_data_packet_t));
+ hdr->MessageType = REMOTE_NDIS_PACKET_MSG;
+ hdr->MessageLength = sizeof(rndis_data_packet_t) + p->tot_len;
+ hdr->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_generic_msg_t);
+ hdr->DataLength = p->tot_len;
+
+ g_rndis_tx_data_length = sizeof(rndis_data_packet_t) + p->tot_len;
+
+ return usbd_ep_start_write(rndis_ep_data[RNDIS_IN_EP_IDX].ep_addr, g_rndis_tx_buffer, g_rndis_tx_data_length);
+}
+#endif
+struct usbd_interface *usbd_rndis_alloc_intf(uint8_t out_ep, uint8_t in_ep, uint8_t int_ep, uint8_t mac[6])
{
struct usbd_interface *intf = (struct usbd_interface *)usb_malloc(sizeof(struct usbd_interface));
if (intf == NULL) {
@@ -417,10 +537,18 @@ struct usbd_interface *usbd_rndis_alloc_intf(uint8_t int_ep, uint8_t mac[6], uin
return NULL;
}
- usbd_rndis_cfg.int_ep = int_ep;
memcpy(usbd_rndis_cfg.mac, mac, 6);
- usbd_rndis_cfg.vendor_id = vendor_id;
- usbd_rndis_cfg.vendor_desc = vendor_desc;
+
+ rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr = out_ep;
+ rndis_ep_data[RNDIS_OUT_EP_IDX].ep_cb = rndis_bulk_out;
+ rndis_ep_data[RNDIS_IN_EP_IDX].ep_addr = in_ep;
+ rndis_ep_data[RNDIS_IN_EP_IDX].ep_cb = rndis_bulk_in;
+ rndis_ep_data[RNDIS_INT_EP_IDX].ep_addr = int_ep;
+ rndis_ep_data[RNDIS_INT_EP_IDX].ep_cb = NULL;
+
+ usbd_add_endpoint(&rndis_ep_data[RNDIS_OUT_EP_IDX]);
+ usbd_add_endpoint(&rndis_ep_data[RNDIS_IN_EP_IDX]);
+ usbd_add_endpoint(&rndis_ep_data[RNDIS_INT_EP_IDX]);
intf->class_interface_handler = rndis_class_interface_request_handler;
intf->class_endpoint_handler = NULL;
diff --git a/class/wireless/usbd_rndis.h b/class/wireless/usbd_rndis.h
index 593dbf78..05ed53ae 100644
--- a/class/wireless/usbd_rndis.h
+++ b/class/wireless/usbd_rndis.h
@@ -8,22 +8,16 @@
#include "usb_cdc.h"
-#define ETH_HEADER_SIZE 14
-#define CONFIG_USBDEV_RNDIS_MTU 1500 /* MTU value */
-
-#ifndef CONFIG_USB_HS
-#define RNDIS_LINK_SPEED 12000000 /* Link baudrate (12Mbit/s for USB-FS) */
-#else
-#define RNDIS_LINK_SPEED 480000000 /* Link baudrate (480Mbit/s for USB-HS) */
-#endif
-
-#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 128
-
#ifdef __cplusplus
extern "C" {
#endif
-struct usbd_interface *usbd_rndis_alloc_intf(uint8_t int_ep, uint8_t mac[6], uint32_t vendor_id, uint8_t *vendor_desc);
+struct usbd_interface *usbd_rndis_alloc_intf(uint8_t out_ep, uint8_t in_ep, uint8_t int_ep, uint8_t mac[6]);
+
+#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
+struct pbuf *usbd_rndis_eth_rx(void);
+int usbd_rndis_eth_tx(struct pbuf *p);
+#endif
#ifdef __cplusplus
}
diff --git a/demo/cdc_rndis_template.c b/demo/cdc_rndis_template.c
new file mode 100644
index 00000000..a056e472
--- /dev/null
+++ b/demo/cdc_rndis_template.c
@@ -0,0 +1,174 @@
+#include "usbd_core.h"
+#include "usbd_rndis.h"
+
+/*!< endpoint address */
+#define CDC_IN_EP 0x81
+#define CDC_OUT_EP 0x02
+#define CDC_INT_EP 0x83
+
+#define USBD_VID 0xEFFF
+#define USBD_PID 0xEFFF
+#define USBD_MAX_POWER 100
+#define USBD_LANGID_STRING 1033
+
+/*!< config descriptor size */
+#define USB_CONFIG_SIZE (9 + CDC_RNDIS_DESCRIPTOR_LEN)
+
+/*!< global descriptor */
+static const uint8_t cdc_descriptor[] = {
+ USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
+ USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+ CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x02),
+ ///////////////////////////////////////
+ /// string0 descriptor
+ ///////////////////////////////////////
+ USB_LANGID_INIT(USBD_LANGID_STRING),
+ ///////////////////////////////////////
+ /// string1 descriptor
+ ///////////////////////////////////////
+ 0x14, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ///////////////////////////////////////
+ /// string2 descriptor
+ ///////////////////////////////////////
+ 0x2A, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ' ', 0x00, /* wcChar9 */
+ 'R', 0x00, /* wcChar10 */
+ 'N', 0x00, /* wcChar11 */
+ 'D', 0x00, /* wcChar12 */
+ 'I', 0x00, /* wcChar13 */
+ 'S', 0x00, /* wcChar14 */
+ ' ', 0x00, /* wcChar15 */
+ 'D', 0x00, /* wcChar16 */
+ 'E', 0x00, /* wcChar17 */
+ 'M', 0x00, /* wcChar18 */
+ 'O', 0x00, /* wcChar19 */
+ ///////////////////////////////////////
+ /// string3 descriptor
+ ///////////////////////////////////////
+ 0x16, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ '2', 0x00, /* wcChar0 */
+ '0', 0x00, /* wcChar1 */
+ '2', 0x00, /* wcChar2 */
+ '2', 0x00, /* wcChar3 */
+ '1', 0x00, /* wcChar4 */
+ '2', 0x00, /* wcChar5 */
+ '3', 0x00, /* wcChar6 */
+ '4', 0x00, /* wcChar7 */
+ '5', 0x00, /* wcChar8 */
+ '6', 0x00, /* wcChar9 */
+#ifdef CONFIG_USB_HS
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x01,
+ 0x40,
+ 0x01,
+ 0x00,
+#endif
+ 0x00
+};
+
+#ifdef RT_USING_LWIP
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <netif/ethernetif.h>
+
+struct eth_device rndis_dev;
+
+void usbd_configure_done_callback(void)
+{
+ eth_device_linkchange(&rndis_dev, RT_TRUE);
+}
+
+uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
+
+static rt_err_t rt_usbd_rndis_control(rt_device_t dev, int cmd, void *args)
+{
+ switch (cmd) {
+ case NIOCTL_GADDR:
+
+ /* get mac address */
+ if (args)
+ rt_memcpy(args, mac, 6);
+ else
+ return -RT_ERROR;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return RT_EOK;
+}
+
+struct pbuf *rt_usbd_rndis_eth_rx(rt_device_t dev)
+{
+ return usbd_rndis_eth_rx();
+}
+
+rt_err_t rt_usbd_rndis_eth_tx(rt_device_t dev, struct pbuf *p)
+{
+ return usbd_rndis_eth_tx(p);
+}
+
+void usbd_rndis_data_recv(uint8_t *data, uint32_t len)
+{
+ eth_device_ready(&rndis_dev);
+}
+
+void rt_usbd_rndis_init(void)
+{
+ rndis_dev.parent.control = rt_usbd_rndis_control;
+ rndis_dev.eth_rx = rt_usbd_rndis_eth_rx;
+ rndis_dev.eth_tx = rt_usbd_rndis_eth_tx;
+
+ eth_device_init(&rndis_dev, "u0");
+
+ eth_device_linkchange(&rndis_dev, RT_FALSE);
+}
+#else
+void usbd_configure_done_callback(void)
+{
+}
+
+#endif /* RT_USING_LWIP */
+
+/* function ------------------------------------------------------------------*/
+void cdc_rndis_init(void)
+{
+#ifdef RT_USING_LWIP
+ rt_usbd_rndis_init();
+#endif
+ usbd_desc_register(cdc_descriptor);
+ usbd_add_interface(usbd_rndis_alloc_intf(CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
+ usbd_add_interface(usbd_rndis_alloc_intf(CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
+ usbd_initialize();
+}