update rndis device driver and template
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 */ \
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -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_VENDOR_DRIVER_VERSION:
|
||||
RNDIS_INQUIRY_PUT_LE32(0x0001);
|
||||
infomation_len = 4;
|
||||
break;
|
||||
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_LINK_SPEED:
|
||||
RNDIS_INQUIRY_PUT_LE32(RNDIS_LINK_SPEED / 100);
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_VENDOR_ID:
|
||||
RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.vendor_id);
|
||||
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);
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
174
demo/cdc_rndis_template.c
Normal file
174
demo/cdc_rndis_template.c
Normal file
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user