Commit 6807f3a8 authored by Johann Fischer's avatar Johann Fischer Committed by Carles Cufi
Browse files

subsys: usb: move descriptor parts to the class drivers



This patch moves the descriptor parts to related class
and function drivers and extends the usb_fix_descriptor
function so that the wTotalLength and bNumInterfaces
are corrected before enumeration.

Signed-off-by: default avatarJohann Fischer <j.fischer@phytec.de>
parent 589dbc4c
Loading
Loading
Loading
Loading
+87 −28
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
 */

#include <init.h>
#include <misc/byteorder.h>

#include <usb/usb_device.h>
#include <usb/usb_common.h>
@@ -45,6 +46,64 @@ static struct k_thread rx_thread_data;
static K_THREAD_STACK_DEFINE(tx_thread_stack, 512);
static struct k_thread tx_thread_data;

struct usb_bluetooth_config {
	struct usb_if_descriptor if0;
	struct usb_ep_descriptor if0_int_ep;
	struct usb_ep_descriptor if0_out_ep;
	struct usb_ep_descriptor if0_in_ep;
} __packed;

USBD_CLASS_DESCR_DEFINE(primary) struct usb_bluetooth_config bluetooth_cfg = {
	/* Interface descriptor 0 */
	.if0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_BLUETOOTH,
		.bAlternateSetting = 0,
		.bNumEndpoints = 3,
		.bInterfaceClass = WIRELESS_DEVICE_CLASS,
		.bInterfaceSubClass = RF_SUBCLASS,
		.bInterfaceProtocol = BLUETOOTH_PROTOCOL,
		.iInterface = 0,
	},

	/* Interrupt Endpoint */
	.if0_int_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_BLUETOOTH_INT_EP_ADDR,
		.bmAttributes = USB_DC_EP_INTERRUPT,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_BLUETOOTH_INT_EP_MPS),
		.bInterval = 0x01,
	},

	/* Data Endpoint OUT */
	.if0_out_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_BLUETOOTH_OUT_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_BLUETOOTH_BULK_EP_MPS),
		.bInterval = 0x01,
	},

	/* Data Endpoint IN */
	.if0_in_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_BLUETOOTH_IN_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_BLUETOOTH_BULK_EP_MPS),
		.bInterval = 0x01,
	},
};

static void hci_rx_thread(void)
{
	SYS_LOG_DBG("Start USB Bluetooth thread");
@@ -115,34 +174,6 @@ static void acl_read_cb(u8_t ep, int size, void *priv)
		     USB_TRANS_READ, acl_read_cb, buf);
}

static int bluetooth_class_handler(struct usb_setup_packet *setup,
				   s32_t *len, u8_t **data)
{
	struct net_buf *buf;

	SYS_LOG_DBG("len %u", *len);

	if (!*len || *len > CMD_BUF_SIZE) {
		SYS_LOG_ERR("Incorrect length: %d\n", *len);
		return -EINVAL;
	}

	buf = net_buf_alloc(&tx_pool, K_NO_WAIT);
	if (!buf) {
		SYS_LOG_ERR("Cannot get free buffer\n");
		return -ENOMEM;
	}

	net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE);
	bt_buf_set_type(buf, BT_BUF_CMD);

	net_buf_add_mem(buf, *data, *len);

	net_buf_put(&tx_queue, buf);

	return 0;
}

static void bluetooth_status_cb(enum usb_dc_status_code status, u8_t *param)
{
	/* Check the USB status and do needed action if required */
@@ -181,6 +212,34 @@ static void bluetooth_status_cb(enum usb_dc_status_code status, u8_t *param)
	}
}

static int bluetooth_class_handler(struct usb_setup_packet *setup,
				   s32_t *len, u8_t **data)
{
	struct net_buf *buf;

	SYS_LOG_DBG("len %u", *len);

	if (!*len || *len > CMD_BUF_SIZE) {
		SYS_LOG_ERR("Incorrect length: %d\n", *len);
		return -EINVAL;
	}

	buf = net_buf_alloc(&tx_pool, K_NO_WAIT);
	if (!buf) {
		SYS_LOG_ERR("Cannot get free buffer\n");
		return -ENOMEM;
	}

	net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE);
	bt_buf_set_type(buf, BT_BUF_CMD);

	net_buf_add_mem(buf, *data, *len);

	net_buf_put(&tx_queue, buf);

	return 0;
}

static struct usb_ep_cfg_data bluetooth_ep_data[] = {
	{
		.ep_cb = usb_transfer_ep_callback,
+127 −2
Original line number Diff line number Diff line
@@ -45,8 +45,8 @@
#include <usb/class/usb_cdc.h>
#include <usb/usb_device.h>
#include <usb/usb_common.h>
#include "../usb_descriptor.h"
#include "../composite.h"
#include <usb_descriptor.h>
#include <composite.h>

#ifndef CONFIG_UART_INTERRUPT_DRIVEN
#error "CONFIG_UART_INTERRUPT_DRIVEN must be set for CDC ACM driver"
@@ -73,6 +73,130 @@
/* Serial state notification timeout */
#define CDC_CONTROL_SERIAL_STATE_TIMEOUT_US 100000

struct usb_cdc_acm_config {
#ifdef CONFIG_USB_COMPOSITE_DEVICE
	struct usb_association_descriptor iad_cdc;
#endif
	struct usb_if_descriptor if0;
	struct cdc_header_descriptor if0_header;
	struct cdc_cm_descriptor if0_cm;
	struct cdc_acm_descriptor if0_acm;
	struct cdc_union_descriptor if0_union;
	struct usb_ep_descriptor if0_int_ep;

	struct usb_if_descriptor if1;
	struct usb_ep_descriptor if1_in_ep;
	struct usb_ep_descriptor if1_out_ep;
} __packed;

USBD_CLASS_DESCR_DEFINE(primary) struct usb_cdc_acm_config cdc_acm_cfg = {
#ifdef CONFIG_USB_COMPOSITE_DEVICE
	.iad_cdc = {
		.bLength = sizeof(struct usb_association_descriptor),
		.bDescriptorType = USB_ASSOCIATION_DESC,
		.bFirstInterface = FIRST_IFACE_CDC_ACM,
		.bInterfaceCount = 0x02,
		.bFunctionClass = COMMUNICATION_DEVICE_CLASS,
		.bFunctionSubClass = ACM_SUBCLASS,
		.bFunctionProtocol = 0,
		.iFunction = 0,
	},
#endif
	/* Interface descriptor */
	.if0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_CDC_ACM,
		.bAlternateSetting = 0,
		.bNumEndpoints = 1,
		.bInterfaceClass = COMMUNICATION_DEVICE_CLASS,
		.bInterfaceSubClass = ACM_SUBCLASS,
		.bInterfaceProtocol = 0,
		.iInterface = 0,
	},
	/* Header Functional Descriptor */
	.if0_header = {
		.bFunctionLength = sizeof(struct cdc_header_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = HEADER_FUNC_DESC,
		.bcdCDC = sys_cpu_to_le16(USB_1_1),
	},
	/* Call Management Functional Descriptor */
	.if0_cm = {
		.bFunctionLength = sizeof(struct cdc_cm_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = CALL_MANAGEMENT_FUNC_DESC,
		.bmCapabilities = 0x02,
		.bDataInterface = 1,
	},
	/* ACM Functional Descriptor */
	.if0_acm = {
		.bFunctionLength = sizeof(struct cdc_acm_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = ACM_FUNC_DESC,
		/* Device supports the request combination of:
		 *	Set_Line_Coding,
		 *	Set_Control_Line_State,
		 *	Get_Line_Coding
		 *	and the notification Serial_State
		 */
		.bmCapabilities = 0x02,
	},
	/* Union Functional Descriptor */
	.if0_union = {
		.bFunctionLength = sizeof(struct cdc_union_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = UNION_FUNC_DESC,
		.bControlInterface = 0,
		.bSubordinateInterface0 = 1,
	},
	/* Endpoint INT */
	.if0_int_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_CDC_ACM_INT_EP_ADDR,
		.bmAttributes = USB_DC_EP_INTERRUPT,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_CDC_ACM_INTERRUPT_EP_MPS),
		.bInterval = 0x0A,
	},
	/* Interface descriptor */
	.if1 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_CDC_ACM + 1,
		.bAlternateSetting = 0,
		.bNumEndpoints = 2,
		.bInterfaceClass = COMMUNICATION_DEVICE_CLASS_DATA,
		.bInterfaceSubClass = 0,
		.bInterfaceProtocol = 0,
		.iInterface = 0,
	},
	/* First Endpoint IN */
	.if1_in_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_CDC_ACM_IN_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_CDC_ACM_BULK_EP_MPS),
		.bInterval = 0x00,
	},
	/* Second Endpoint OUT */
	.if1_out_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_CDC_ACM_OUT_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_CDC_ACM_BULK_EP_MPS),
		.bInterval = 0x00,
	},
};

struct device *cdc_acm_dev;

static struct k_sem poll_wait_sem;
@@ -366,6 +490,7 @@ static int cdc_acm_init(struct device *dev)
	}
#else
	struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);

	cdc_acm_config.interface.payload_data = dev_data->interface_data;
	cdc_acm_config.usb_device_description = usb_get_device_descriptor();
	/* Initialize the USB driver with the right configuration */
+53 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#define SYS_LOG_DOMAIN "usb/hid"
#include <logging/sys_log.h>

#include <misc/byteorder.h>
#include <usb_device.h>
#include <usb_common.h>

@@ -20,6 +21,58 @@
#include <composite.h>
#endif

struct usb_hid_config {
	struct usb_if_descriptor if0;
	struct usb_hid_descriptor if0_hid;
	struct usb_ep_descriptor if0_int_ep;
} __packed;

USBD_CLASS_DESCR_DEFINE(primary) struct usb_hid_config hid_cfg = {
	/* Interface descriptor */
	.if0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_HID,
		.bAlternateSetting = 0,
		.bNumEndpoints = 1,
		.bInterfaceClass = HID_CLASS,
		.bInterfaceSubClass = 0,
		.bInterfaceProtocol = 0,
		.iInterface = 0,
	},
	.if0_hid = {
		.bLength = sizeof(struct usb_hid_descriptor),
		.bDescriptorType = USB_HID_DESC,
		.bcdHID = sys_cpu_to_le16(USB_1_1),
		.bCountryCode = 0,
		.bNumDescriptors = 1,
		.subdesc[0] = {
			.bDescriptorType = USB_HID_REPORT_DESC,
			/*
			 * descriptor length needs to be set
			 * after initialization
			 */
			.wDescriptorLength = 0,
		},
	},
	.if0_int_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_HID_INT_EP_ADDR,
		.bmAttributes = USB_DC_EP_INTERRUPT,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_HID_INTERRUPT_EP_MPS),
		.bInterval = 0x09,
	},
};

static void usb_set_hid_report_size(u16_t report_desc_size)
{
	hid_cfg.if0_hid.subdesc[0].wDescriptorLength =
		sys_cpu_to_le16(report_desc_size);
}

static struct hid_device_info {
	const u8_t *report_desc;
	size_t report_size;
+42 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <init.h>
#include <errno.h>
#include <string.h>
#include <misc/byteorder.h>
#include <misc/__assert.h>
#include <disk_access.h>
#include <usb/class/usb_msc.h>
@@ -59,6 +60,47 @@
#define THREAD_OP_WRITE_QUEUED		3
#define THREAD_OP_WRITE_DONE		4

struct usb_mass_config {
	struct usb_if_descriptor if0;
	struct usb_ep_descriptor if0_in_ep;
	struct usb_ep_descriptor if0_out_ep;
} __packed;

USBD_CLASS_DESCR_DEFINE(primary) struct usb_mass_config mass_cfg = {
	/* Interface descriptor */
	.if0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_MASS_STORAGE,
		.bAlternateSetting = 0,
		.bNumEndpoints = 2,
		.bInterfaceClass = MASS_STORAGE_CLASS,
		.bInterfaceSubClass = SCSI_TRANSPARENT_SUBCLASS,
		.bInterfaceProtocol = BULK_ONLY_PROTOCOL,
		.iInterface = 0,
	},
	/* First Endpoint IN */
	.if0_in_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_MASS_STORAGE_IN_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(CONFIG_MASS_STORAGE_BULK_EP_MPS),
		.bInterval = 0x00,
	},
	/* Second Endpoint OUT */
	.if0_out_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_MASS_STORAGE_OUT_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(CONFIG_MASS_STORAGE_BULK_EP_MPS),
		.bInterval = 0x00,
	},
};

static volatile int thread_op;
static K_THREAD_STACK_DEFINE(mass_thread_stack, DISK_THREAD_STACK_SZ);
static struct k_thread mass_thread_data;
+340 −0
Original line number Diff line number Diff line
@@ -30,6 +30,346 @@
#include <composite.h>
#include "netusb.h"

#ifdef CONFIG_USB_DEVICE_NETWORK_RNDIS
struct usb_rndis_config {
#ifdef CONFIG_USB_COMPOSITE_DEVICE
	struct usb_association_descriptor iad;
#endif
	struct usb_if_descriptor if0;
	struct cdc_header_descriptor if0_header;
	struct cdc_cm_descriptor if0_cm;
	struct cdc_acm_descriptor if0_acm;
	struct cdc_union_descriptor if0_union;
	struct usb_ep_descriptor if0_int_ep;

	struct usb_if_descriptor if1;
	struct usb_ep_descriptor if1_in_ep;
	struct usb_ep_descriptor if1_out_ep;
} __packed;

USBD_CLASS_DESCR_DEFINE(primary) struct usb_rndis_config rndis_cfg = {
#ifdef CONFIG_USB_COMPOSITE_DEVICE
	.iad = {
		.bLength = sizeof(struct usb_association_descriptor),
		.bDescriptorType = USB_ASSOCIATION_DESC,
		.bFirstInterface = FIRST_IFACE_RNDIS,
		.bInterfaceCount = 0x02,
		.bFunctionClass = COMMUNICATION_DEVICE_CLASS,
		.bFunctionSubClass = 6,
		.bFunctionProtocol = 0,
		.iFunction = 0,
	},
#endif
	/* Interface descriptor 0 */
	/* CDC Communication interface */
	.if0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_RNDIS,
		.bAlternateSetting = 0,
		.bNumEndpoints = 1,
		.bInterfaceClass = COMMUNICATION_DEVICE_CLASS,
		.bInterfaceSubClass = ACM_SUBCLASS,
		.bInterfaceProtocol = ACM_VENDOR_PROTOCOL,
		.iInterface = 0,
	},
	/* Header Functional Descriptor */
	.if0_header = {
		.bFunctionLength = sizeof(struct cdc_header_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = HEADER_FUNC_DESC,
		.bcdCDC = sys_cpu_to_le16(USB_1_1),
	},
	/* Call Management Functional Descriptor */
	.if0_cm = {
		.bFunctionLength = sizeof(struct cdc_cm_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = CALL_MANAGEMENT_FUNC_DESC,
		.bmCapabilities = 0x00,
		.bDataInterface = 1,
	},
	/* ACM Functional Descriptor */
	.if0_acm = {
		.bFunctionLength = sizeof(struct cdc_acm_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = ACM_FUNC_DESC,
		/* Device supports the request combination of:
		 *	Set_Line_Coding,
		 *	Set_Control_Line_State,
		 *	Get_Line_Coding
		 *	and the notification Serial_State
		 */
		.bmCapabilities = 0x00,
	},
	/* Union Functional Descriptor */
	.if0_union = {
		.bFunctionLength = sizeof(struct cdc_union_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = UNION_FUNC_DESC,
		.bControlInterface = 0,
		.bSubordinateInterface0 = 1,
	},
	/* Notification EP Descriptor */
	.if0_int_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_RNDIS_INT_EP_ADDR,
		.bmAttributes = USB_DC_EP_INTERRUPT,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_RNDIS_INTERRUPT_EP_MPS),
		.bInterval = 0x09,
	},

	/* Interface descriptor 1 */
	/* CDC Data Interface */
	.if1 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_RNDIS + 1,
		.bAlternateSetting = 0,
		.bNumEndpoints = 2,
		.bInterfaceClass = COMMUNICATION_DEVICE_CLASS_DATA,
		.bInterfaceSubClass = 0,
		.bInterfaceProtocol = 0,
		.iInterface = 0,
	},
	/* Data Endpoint IN */
	.if1_in_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_RNDIS_IN_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_RNDIS_BULK_EP_MPS),
		.bInterval = 0x00,
	},
	/* Data Endpoint OUT */
	.if1_out_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_RNDIS_OUT_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_RNDIS_BULK_EP_MPS),
		.bInterval = 0x00,
	},
};
#endif /* CONFIG_USB_DEVICE_NETWORK_RNDIS */

#ifdef CONFIG_USB_DEVICE_NETWORK_ECM
struct usb_cdc_ecm_config {
#ifdef CONFIG_USB_COMPOSITE_DEVICE
	struct usb_association_descriptor iad;
#endif
	struct usb_if_descriptor if0;
	struct cdc_header_descriptor if0_header;
	struct cdc_union_descriptor if0_union;
	struct cdc_ecm_descriptor if0_netfun_ecm;
	struct usb_ep_descriptor if0_int_ep;

	struct usb_if_descriptor if1_0;

	struct usb_if_descriptor if1_1;
	struct usb_ep_descriptor if1_1_in_ep;
	struct usb_ep_descriptor if1_1_out_ep;
} __packed;

USBD_CLASS_DESCR_DEFINE(primary) struct usb_cdc_ecm_config cdc_ecm_cfg = {
#ifdef CONFIG_USB_COMPOSITE_DEVICE
	.iad = {
		.bLength = sizeof(struct usb_association_descriptor),
		.bDescriptorType = USB_ASSOCIATION_DESC,
		.bFirstInterface = FIRST_IFACE_CDC_ECM,
		.bInterfaceCount = 0x02,
		.bFunctionClass = COMMUNICATION_DEVICE_CLASS,
		.bFunctionSubClass = ECM_SUBCLASS,
		.bFunctionProtocol = 0,
		.iFunction = 0,
	},
#endif
	/* Interface descriptor 0 */
	/* CDC Communication interface */
	.if0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_CDC_ECM,
		.bAlternateSetting = 0,
		.bNumEndpoints = 1,
		.bInterfaceClass = COMMUNICATION_DEVICE_CLASS,
		.bInterfaceSubClass = ECM_SUBCLASS,
		.bInterfaceProtocol = 0,
		.iInterface = 0,
	},
	/* Header Functional Descriptor */
	.if0_header = {
		.bFunctionLength = sizeof(struct cdc_header_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = HEADER_FUNC_DESC,
		.bcdCDC = sys_cpu_to_le16(USB_1_1),
	},
	/* Union Functional Descriptor */
	.if0_union = {
		.bFunctionLength = sizeof(struct cdc_union_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = UNION_FUNC_DESC,
		.bControlInterface = 0,
		.bSubordinateInterface0 = 1,
	},
	/* Ethernet Networking Functional descriptor */
	.if0_netfun_ecm = {
		.bFunctionLength = sizeof(struct cdc_ecm_descriptor),
		.bDescriptorType = CS_INTERFACE,
		.bDescriptorSubtype = ETHERNET_FUNC_DESC,
		.iMACAddress = 4,
		.bmEthernetStatistics = sys_cpu_to_le32(0), /* None */
		.wMaxSegmentSize = sys_cpu_to_le16(1514),
		.wNumberMCFilters = sys_cpu_to_le16(0), /* None */
		.bNumberPowerFilters = 0, /* No wake up */
	},
	/* Notification EP Descriptor */
	.if0_int_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_CDC_ECM_INT_EP_ADDR,
		.bmAttributes = USB_DC_EP_INTERRUPT,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_CDC_ECM_INTERRUPT_EP_MPS),
		.bInterval = 0x09,
	},

	/* Interface descriptor 1/0 */
	/* CDC Data Interface */
	.if1_0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_CDC_ECM + 1,
		.bAlternateSetting = 0,
		.bNumEndpoints = 0,
		.bInterfaceClass = COMMUNICATION_DEVICE_CLASS_DATA,
		.bInterfaceSubClass = 0,
		.bInterfaceProtocol = 0,
		.iInterface = 0,
	},

	/* Interface descriptor 1/1 */
	/* CDC Data Interface */
	.if1_1 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_CDC_ECM + 1,
		.bAlternateSetting = 1,
		.bNumEndpoints = 2,
		.bInterfaceClass = COMMUNICATION_DEVICE_CLASS_DATA,
		.bInterfaceSubClass = ECM_SUBCLASS,
		.bInterfaceProtocol = 0,
		.iInterface = 0,
	},
	/* Data Endpoint IN */
	.if1_1_in_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_CDC_ECM_IN_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_CDC_ECM_BULK_EP_MPS),
		.bInterval = 0x00,
	},
	/* Data Endpoint OUT */
	.if1_1_out_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_CDC_ECM_OUT_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_CDC_ECM_BULK_EP_MPS),
		.bInterval = 0x00,
	},
};

struct usb_cdc_ecm_mac_descr {
	u8_t bLength;
	u8_t bDescriptorType;
	u8_t bString[USB_BSTRING_LENGTH(CONFIG_USB_DEVICE_NETWORK_ECM_MAC)];
} __packed;

USBD_STRING_DESCR_DEFINE(primary) struct usb_cdc_ecm_mac_descr utf16le_mac = {
	.bLength = USB_STRING_DESCRIPTOR_LENGTH(
			CONFIG_USB_DEVICE_NETWORK_ECM_MAC),
	.bDescriptorType = USB_STRING_DESC,
	.bString = CONFIG_USB_DEVICE_NETWORK_ECM_MAC
};
#endif

#ifdef CONFIG_USB_DEVICE_NETWORK_EEM
struct usb_cdc_eem_config {
#ifdef CONFIG_USB_COMPOSITE_DEVICE
	struct usb_association_descriptor iad;
#endif
	struct usb_if_descriptor if0;
	struct usb_ep_descriptor if0_in_ep;
	struct usb_ep_descriptor if0_out_ep;
} __packed;

USBD_CLASS_DESCR_DEFINE(primary) struct usb_cdc_eem_config cdc_eem_cfg = {
#ifdef CONFIG_USB_COMPOSITE_DEVICE
	.iad = {
		.bLength = sizeof(struct usb_association_descriptor),
		.bDescriptorType = USB_ASSOCIATION_DESC,
		.bFirstInterface = FIRST_IFACE_CDC_EEM,
		.bInterfaceCount = 0x01,
		.bFunctionClass = COMMUNICATION_DEVICE_CLASS,
		.bFunctionSubClass = EEM_SUBCLASS,
		.bFunctionProtocol = 0,
		.iFunction = 0,
	},
#endif

	/* Interface descriptor 0 */
	/* CDC Communication interface */
	.if0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_INTERFACE_DESC,
		.bInterfaceNumber = FIRST_IFACE_CDC_EEM,
		.bAlternateSetting = 0,
		.bNumEndpoints = 2,
		.bInterfaceClass = COMMUNICATION_DEVICE_CLASS,
		.bInterfaceSubClass = EEM_SUBCLASS,
		.bInterfaceProtocol = EEM_PROTOCOL,
		.iInterface = 0,
	},

	/* Data Endpoint IN */
	.if0_in_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_CDC_EEM_IN_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_CDC_EEM_BULK_EP_MPS),
		.bInterval = 0x00,
	},

	/* Data Endpoint OUT */
	.if0_out_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_ENDPOINT_DESC,
		.bEndpointAddress = CONFIG_CDC_EEM_OUT_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(
			CONFIG_CDC_EEM_BULK_EP_MPS),
		.bInterval = 0x00,
	},
};
#endif /* CONFIG_USB_DEVICE_NETWORK_EEM */

static struct __netusb {
	struct net_if *iface;
	bool enabled;
Loading