⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ether.c

📁 linux下面gadget设备驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* compute wTotalLength on the fly */	.bNumInterfaces =       2,	.bConfigurationValue =  DEV_RNDIS_CONFIG_VALUE,	.iConfiguration =       STRING_RNDIS,	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,	.bMaxPower =            50,};#endif/* * Compared to the simple CDC subset, the full CDC Ethernet model adds * three class descriptors, two interface descriptors, optional status * endpoint.  Both have a "data" interface and two bulk endpoints. * There are also differences in how control requests are handled. * * RNDIS shares a lot with CDC-Ethernet, since it's a variant of the * CDC-ACM (modem) spec.  Unfortunately MSFT's RNDIS driver is buggy; it * may hang or oops.  Since bugfixes (or accurate specs, letting Linux * work around those bugs) are unlikely to ever come from MSFT, you may * wish to avoid using RNDIS. * * MCCI offers an alternative to RNDIS if you need to connect to Windows * but have hardware that can't support CDC Ethernet.   We add descriptors * to present the CDC Subset as a (nonconformant) CDC MDLM variant called * "SAFE".  That borrows from both CDC Ethernet and CDC MDLM.  You can * get those drivers from MCCI, or bundled with various products. */#ifdef	DEV_CONFIG_CDCstatic struct usb_interface_descriptorcontrol_intf = {	.bLength =		sizeof control_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	0,	/* status endpoint is optional; this may be patched later */	.bNumEndpoints =	1,	.bInterfaceClass =	USB_CLASS_COMM,	.bInterfaceSubClass =	USB_CDC_SUBCLASS_ETHERNET,	.bInterfaceProtocol =	USB_CDC_PROTO_NONE,	.iInterface =		STRING_CONTROL,};#endif#ifdef	CONFIG_USB_ETH_RNDISstatic const struct usb_interface_descriptorrndis_control_intf = {	.bLength =              sizeof rndis_control_intf,	.bDescriptorType =      USB_DT_INTERFACE,	.bInterfaceNumber =     0,	.bNumEndpoints =        1,	.bInterfaceClass =      USB_CLASS_COMM,	.bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,	.bInterfaceProtocol =   USB_CDC_ACM_PROTO_VENDOR,	.iInterface =           STRING_RNDIS_CONTROL,};#endifstatic const struct usb_cdc_header_desc header_desc = {	.bLength =		sizeof header_desc,	.bDescriptorType =	USB_DT_CS_INTERFACE,	.bDescriptorSubType =	USB_CDC_HEADER_TYPE,	.bcdCDC =		__constant_cpu_to_le16 (0x0110),};#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)static const struct usb_cdc_union_desc union_desc = {	.bLength =		sizeof union_desc,	.bDescriptorType =	USB_DT_CS_INTERFACE,	.bDescriptorSubType =	USB_CDC_UNION_TYPE,	.bMasterInterface0 =	0,	/* index of control interface */	.bSlaveInterface0 =	1,	/* index of DATA interface */};#endif	/* CDC || RNDIS */#ifdef	CONFIG_USB_ETH_RNDISstatic const struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = {	.bLength =		sizeof call_mgmt_descriptor,	.bDescriptorType =	USB_DT_CS_INTERFACE,	.bDescriptorSubType =	USB_CDC_CALL_MANAGEMENT_TYPE,	.bmCapabilities =	0x00,	.bDataInterface =	0x01,};static const struct usb_cdc_acm_descriptor acm_descriptor = {	.bLength =		sizeof acm_descriptor,	.bDescriptorType =	USB_DT_CS_INTERFACE,	.bDescriptorSubType =	USB_CDC_ACM_TYPE,	.bmCapabilities =	0x00,};#endif#ifndef DEV_CONFIG_CDC/* "SAFE" loosely follows CDC WMC MDLM, violating the spec in various * ways:  data endpoints live in the control interface, there's no data * interface, and it's not used to talk to a cell phone radio. */static const struct usb_cdc_mdlm_desc mdlm_desc = {	.bLength =		sizeof mdlm_desc,	.bDescriptorType =	USB_DT_CS_INTERFACE,	.bDescriptorSubType =	USB_CDC_MDLM_TYPE,	.bcdVersion =		__constant_cpu_to_le16(0x0100),	.bGUID = {		0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,		0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,	},};/* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we * can't really use its struct.  All we do here is say that we're using * the submode of "SAFE" which directly matches the CDC Subset. */static const u8 mdlm_detail_desc[] = {	6,	USB_DT_CS_INTERFACE,	USB_CDC_MDLM_DETAIL_TYPE,	0,	/* "SAFE" */	0,	/* network control capabilities (none) */	0,	/* network data capabilities ("raw" encapsulation) */};#endifstatic const struct usb_cdc_ether_desc ether_desc = {	.bLength =		sizeof ether_desc,	.bDescriptorType =	USB_DT_CS_INTERFACE,	.bDescriptorSubType =	USB_CDC_ETHERNET_TYPE,	/* this descriptor actually adds value, surprise! */	.iMACAddress =		STRING_ETHADDR,	.bmEthernetStatistics =	__constant_cpu_to_le32 (0), /* no statistics */	.wMaxSegmentSize =	__constant_cpu_to_le16 (ETH_FRAME_LEN),	.wNumberMCFilters =	__constant_cpu_to_le16 (0),	.bNumberPowerFilters =	0,};#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)/* include the status endpoint if we can, even where it's optional. * use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one * packet, to simplify cancellation; and a big transfer interval, to * waste less bandwidth. * * some drivers (like Linux 2.4 cdc-ether!) "need" it to exist even * if they ignore the connect/disconnect notifications that real aether * can provide.  more advanced cdc configurations might want to support * encapsulated commands (vendor-specific, using control-OUT). * * RNDIS requires the status endpoint, since it uses that encapsulation * mechanism for its funky RPC scheme. */#define LOG2_STATUS_INTERVAL_MSEC	5	/* 1 << 5 == 32 msec */#define STATUS_BYTECOUNT		16	/* 8 byte header + data */static struct usb_endpoint_descriptorfs_status_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bEndpointAddress =	USB_DIR_IN,	.bmAttributes =		USB_ENDPOINT_XFER_INT,	.wMaxPacketSize =	__constant_cpu_to_le16 (STATUS_BYTECOUNT),	.bInterval =		1 << LOG2_STATUS_INTERVAL_MSEC,};#endif#ifdef	DEV_CONFIG_CDC/* the default data interface has no endpoints ... */static const struct usb_interface_descriptordata_nop_intf = {	.bLength =		sizeof data_nop_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	1,	.bAlternateSetting =	0,	.bNumEndpoints =	0,	.bInterfaceClass =	USB_CLASS_CDC_DATA,	.bInterfaceSubClass =	0,	.bInterfaceProtocol =	0,};/* ... but the "real" data interface has two bulk endpoints */static const struct usb_interface_descriptordata_intf = {	.bLength =		sizeof data_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	1,	.bAlternateSetting =	1,	.bNumEndpoints =	2,	.bInterfaceClass =	USB_CLASS_CDC_DATA,	.bInterfaceSubClass =	0,	.bInterfaceProtocol =	0,	.iInterface =		STRING_DATA,};#endif#ifdef	CONFIG_USB_ETH_RNDIS/* RNDIS doesn't activate by changing to the "real" altsetting */static const struct usb_interface_descriptorrndis_data_intf = {	.bLength =		sizeof rndis_data_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	1,	.bAlternateSetting =	0,	.bNumEndpoints =	2,	.bInterfaceClass =	USB_CLASS_CDC_DATA,	.bInterfaceSubClass =	0,	.bInterfaceProtocol =	0,	.iInterface =		STRING_DATA,};#endif#ifdef DEV_CONFIG_SUBSET/* * "Simple" CDC-subset option is a simple vendor-neutral model that most * full speed controllers can handle:  one interface, two bulk endpoints. * * To assist host side drivers, we fancy it up a bit, and add descriptors * so some host side drivers will understand it as a "SAFE" variant. */static const struct usb_interface_descriptorsubset_data_intf = {	.bLength =		sizeof subset_data_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	0,	.bAlternateSetting =	0,	.bNumEndpoints =	2,	.bInterfaceClass =      USB_CLASS_COMM,	.bInterfaceSubClass =	USB_CDC_SUBCLASS_MDLM,	.bInterfaceProtocol =	0,	.iInterface =		STRING_DATA,};#endif	/* SUBSET */static struct usb_endpoint_descriptorfs_source_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bEndpointAddress =	USB_DIR_IN,	.bmAttributes =		USB_ENDPOINT_XFER_BULK,};static struct usb_endpoint_descriptorfs_sink_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bEndpointAddress =	USB_DIR_OUT,	.bmAttributes =		USB_ENDPOINT_XFER_BULK,};static const struct usb_descriptor_header *fs_eth_function [11] = {	(struct usb_descriptor_header *) &otg_descriptor,#ifdef DEV_CONFIG_CDC	/* "cdc" mode descriptors */	(struct usb_descriptor_header *) &control_intf,	(struct usb_descriptor_header *) &header_desc,	(struct usb_descriptor_header *) &union_desc,	(struct usb_descriptor_header *) &ether_desc,	/* NOTE: status endpoint may need to be removed */	(struct usb_descriptor_header *) &fs_status_desc,	/* data interface, with altsetting */	(struct usb_descriptor_header *) &data_nop_intf,	(struct usb_descriptor_header *) &data_intf,	(struct usb_descriptor_header *) &fs_source_desc,	(struct usb_descriptor_header *) &fs_sink_desc,	NULL,#endif /* DEV_CONFIG_CDC */};static inline void __init fs_subset_descriptors(void){#ifdef DEV_CONFIG_SUBSET	/* behavior is "CDC Subset"; extra descriptors say "SAFE" */	fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;	fs_eth_function[2] = (struct usb_descriptor_header *) &header_desc;	fs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc;	fs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc;	fs_eth_function[5] = (struct usb_descriptor_header *) &ether_desc;	fs_eth_function[6] = (struct usb_descriptor_header *) &fs_source_desc;	fs_eth_function[7] = (struct usb_descriptor_header *) &fs_sink_desc;	fs_eth_function[8] = NULL;#else	fs_eth_function[1] = NULL;#endif}#ifdef	CONFIG_USB_ETH_RNDISstatic const struct usb_descriptor_header *fs_rndis_function [] = {	(struct usb_descriptor_header *) &otg_descriptor,	/* control interface matches ACM, not Ethernet */	(struct usb_descriptor_header *) &rndis_control_intf,	(struct usb_descriptor_header *) &header_desc,	(struct usb_descriptor_header *) &call_mgmt_descriptor,	(struct usb_descriptor_header *) &acm_descriptor,	(struct usb_descriptor_header *) &union_desc,	(struct usb_descriptor_header *) &fs_status_desc,	/* data interface has no altsetting */	(struct usb_descriptor_header *) &rndis_data_intf,	(struct usb_descriptor_header *) &fs_source_desc,	(struct usb_descriptor_header *) &fs_sink_desc,	NULL,};#endif/* * usb 2.0 devices need to expose both high speed and full speed * descriptors, unless they only run at full speed. */#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)static struct usb_endpoint_descriptorhs_status_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bmAttributes =		USB_ENDPOINT_XFER_INT,	.wMaxPacketSize =	__constant_cpu_to_le16 (STATUS_BYTECOUNT),	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4,};#endif /* DEV_CONFIG_CDC */static struct usb_endpoint_descriptorhs_source_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bmAttributes =		USB_ENDPOINT_XFER_BULK,	.wMaxPacketSize =	__constant_cpu_to_le16 (512),};static struct usb_endpoint_descriptorhs_sink_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bmAttributes =		USB_ENDPOINT_XFER_BULK,	.wMaxPacketSize =	__constant_cpu_to_le16 (512),};static struct usb_qualifier_descriptordev_qualifier = {	.bLength =		sizeof dev_qualifier,	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,	.bcdUSB =		__constant_cpu_to_le16 (0x0200),	.bDeviceClass =		USB_CLASS_COMM,	.bNumConfigurations =	1,};static const struct usb_descriptor_header *hs_eth_function [11] = {	(struct usb_descriptor_header *) &otg_descriptor,#ifdef DEV_CONFIG_CDC	/* "cdc" mode descriptors */	(struct usb_descriptor_header *) &control_intf,	(struct usb_descriptor_header *) &header_desc,	(struct usb_descriptor_header *) &union_desc,	(struct usb_descriptor_header *) &ether_desc,	/* NOTE: status endpoint may need to be removed */	(struct usb_descriptor_header *) &hs_status_desc,	/* data interface, with altsetting */	(struct usb_descriptor_header *) &data_nop_intf,	(struct usb_descriptor_header *) &data_intf,	(struct usb_descriptor_header *) &hs_source_desc,	(struct usb_descriptor_header *) &hs_sink_desc,	NULL,#endif /* DEV_CONFIG_CDC */};static inline void __init hs_subset_descriptors(void){#ifdef DEV_CONFIG_SUBSET	/* behavior is "CDC Subset"; extra descriptors say "SAFE" */	hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;	hs_eth_function[2] = (struct usb_descriptor_header *) &header_desc;	hs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc;	hs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc;	hs_eth_function[5] = (struct usb_descriptor_header *) &ether_desc;	hs_eth_function[6] = (struct usb_descriptor_header *) &hs_source_desc;	hs_eth_function[7] = (struct usb_descriptor_header *) &hs_sink_desc;	hs_eth_function[8] = NULL;#else	hs_eth_function[1] = NULL;#endif}#ifdef	CONFIG_USB_ETH_RNDISstatic const struct usb_descriptor_header *hs_rndis_function [] = {	(struct usb_descriptor_header *) &otg_descriptor,	/* control interface matches ACM, not Ethernet */	(struct usb_descriptor_header *) &rndis_control_intf,	(struct usb_descriptor_header *) &header_desc,	(struct usb_descriptor_header *) &call_mgmt_descriptor,	(struct usb_descriptor_header *) &acm_descriptor,	(struct usb_descriptor_header *) &union_desc,	(struct usb_descriptor_header *) &hs_status_desc,	/* data interface has no altsetting */	(struct usb_descriptor_header *) &rndis_data_intf,	(struct usb_descriptor_header *) &hs_source_desc,	(struct usb_descriptor_header *) &hs_sink_desc,	NULL,};#endif/* maxpacket and other transfer characteristics vary by speed. */static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,		struct usb_endpoint_descriptor *fs){	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)		return hs;	return fs;}/*-------------------------------------------------------------------------*//* descriptors that are built on-demand */static char				manufacturer [50];static char				product_desc [40] = DRIVER_DESC;static char				serial_number [20];/* address that the host will use ... usually assigned at random */static char				ethaddr [2 * ETH_ALEN + 1];/* static strings, in UTF-8 */static struct usb_string		strings [] = {	{ STRING_MANUFACTURER,	manufacturer, },	{ STRING_PRODUCT,	product_desc, },	{ STRING_SERIALNUMBER,	serial_number, },	{ STRING_DATA,		"Ethernet Data", },	{ STRING_ETHADDR,	ethaddr, },#ifdef	DEV_CONFIG_CDC	{ STRING_CDC,		"CDC Ethernet", },	{ STRING_CONTROL,	"CDC Communications Control", },#endif#ifdef	DEV_CONFIG_SUBSET	{ STRING_SUBSET,	"CDC Ethernet Subset", },#endif#ifdef	CONFIG_USB_ETH_RNDIS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -