Commit 166685d0 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB Gadget: RNDIS/Ethernet Gadget Driver (1/2)

This patch adds the RNDIS message engine and kbuild/kconfig
support for it.  This is currently labeled EXPERIMENTAL.

Patch contributed by Robert Schwebel, and developed with
support from Auerswald GmbH.
parent 21d554cc
......@@ -219,9 +219,11 @@ config USB_ETH
favor of simpler vendor-specific hardware, but is widely
supported by firmware for smart network devices.
- On hardware can't implement that protocol, a simpler approach
- On hardware can't implement that protocol, a simple CDC subset
is used, placing fewer demands on USB.
RNDIS support is a third option, more demanding than that subset.
Within the USB device, this gadget driver exposes a network device
"usbX", where X depends on what other networking devices you have.
Treat it like a two-node Ethernet link: host, and gadget.
......@@ -235,6 +237,19 @@ config USB_ETH
Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "g_ether".
config USB_ETH_RNDIS
bool "RNDIS support (EXPERIMENTAL)"
depends on USB_ETH && EXPERIMENTAL
default y
help
Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
and Microsoft provides redistributable binary RNDIS drivers for
older versions of Windows.
If you say "y" here, the Ethernet gadget driver will try to provide
a second device configuration, supporting RNDIS to talk to such
Microsoft USB hosts.
config USB_GADGETFS
tristate "Gadget Filesystem (EXPERIMENTAL)"
depends on EXPERIMENTAL
......
......@@ -14,6 +14,10 @@ g_ether-objs := ether.o usbstring.o config.o epautoconf.o
g_serial-objs := serial.o usbstring.o
gadgetfs-objs := inode.o
g_file_storage-objs := file_storage.o usbstring.o
ifeq ($(CONFIG_USB_ETH_RNDIS),y)
g_ether-objs += rndis.o
endif
obj-$(CONFIG_USB_ZERO) += g_zero.o
obj-$(CONFIG_USB_ETH) += g_ether.o
......
/*
* ndis.h
*
* ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de>
*
* Thanks to the cygwin development team,
* espacially to Casper S. Hornstrup <chorns@users.sourceforge.net>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef _LINUX_NDIS_H
#define _LINUX_NDIS_H
#define NDIS_STATUS_MULTICAST_FULL 0xC0010009
#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A
#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B
/* NDIS_PNP_CAPABILITIES.Flags constants */
#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001
#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002
#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004
/* Required Object IDs (OIDs) */
#define OID_GEN_SUPPORTED_LIST 0x00010101
#define OID_GEN_HARDWARE_STATUS 0x00010102
#define OID_GEN_MEDIA_SUPPORTED 0x00010103
#define OID_GEN_MEDIA_IN_USE 0x00010104
#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106
#define OID_GEN_LINK_SPEED 0x00010107
#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108
#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B
#define OID_GEN_VENDOR_ID 0x0001010C
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E
#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F
#define OID_GEN_DRIVER_VERSION 0x00010110
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111
#define OID_GEN_PROTOCOL_OPTIONS 0x00010112
#define OID_GEN_MAC_OPTIONS 0x00010113
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115
#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116
#define OID_GEN_SUPPORTED_GUIDS 0x00010117
#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118
#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119
#define OID_GEN_MACHINE_NAME 0x0001021A
#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B
#define OID_GEN_VLAN_ID 0x0001021C
/* Optional OIDs */
#define OID_GEN_MEDIA_CAPABILITIES 0x00010201
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202
/* Required statistics OIDs */
#define OID_GEN_XMIT_OK 0x00020101
#define OID_GEN_RCV_OK 0x00020102
#define OID_GEN_XMIT_ERROR 0x00020103
#define OID_GEN_RCV_ERROR 0x00020104
#define OID_GEN_RCV_NO_BUFFER 0x00020105
/* Optional statistics OIDs */
#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201
#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203
#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205
#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207
#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209
#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B
#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
#define OID_GEN_RCV_CRC_ERROR 0x0002020D
#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
#define OID_GEN_GET_TIME_CAPS 0x0002020F
#define OID_GEN_GET_NETCARD_TIME 0x00020210
#define OID_GEN_NETCARD_LOAD 0x00020211
#define OID_GEN_DEVICE_PROFILE 0x00020212
#define OID_GEN_INIT_TIME_MS 0x00020213
#define OID_GEN_RESET_COUNTS 0x00020214
#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215
#define OID_GEN_FRIENDLY_NAME 0x00020216
#define OID_GEN_MINIPORT_INFO 0x00020217
#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218
/* IEEE 802.3 (Ethernet) OIDs */
#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001
#define OID_802_3_PERMANENT_ADDRESS 0x01010101
#define OID_802_3_CURRENT_ADDRESS 0x01010102
#define OID_802_3_MULTICAST_LIST 0x01010103
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104
#define OID_802_3_MAC_OPTIONS 0x01010105
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
#define OID_802_3_XMIT_DEFERRED 0x01020201
#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
#define OID_802_3_RCV_OVERRUN 0x01020203
#define OID_802_3_XMIT_UNDERRUN 0x01020204
#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205
#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
/* OID_GEN_MINIPORT_INFO constants */
#define NDIS_MINIPORT_BUS_MASTER 0x00000001
#define NDIS_MINIPORT_WDM_DRIVER 0x00000002
#define NDIS_MINIPORT_SG_LIST 0x00000004
#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008
#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010
#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020
#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040
#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080
#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100
#define NDIS_MINIPORT_IS_NDIS_5 0x00000200
#define NDIS_MINIPORT_IS_CO 0x00000400
#define NDIS_MINIPORT_DESERIALIZE 0x00000800
#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000
#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000
#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000
#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000
#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000
#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000
#define NDIS_MINIPORT_HIDDEN 0x00040000
#define NDIS_MINIPORT_SWENUM 0x00080000
#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000
#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000
#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000
#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000
#define NDIS_MINIPORT_64BITS_DMA 0x01000000
#define NDIS_MEDIUM_802_3 0x00000000
#define NDIS_MEDIUM_802_5 0x00000001
#define NDIS_MEDIUM_FDDI 0x00000002
#define NDIS_MEDIUM_WAN 0x00000003
#define NDIS_MEDIUM_LOCAL_TALK 0x00000004
#define NDIS_MEDIUM_DIX 0x00000005
#define NDIS_MEDIUM_ARCENT_RAW 0x00000006
#define NDIS_MEDIUM_ARCENT_878_2 0x00000007
#define NDIS_MEDIUM_ATM 0x00000008
#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009
#define NDIS_MEDIUM_IRDA 0x0000000A
#define NDIS_MEDIUM_BPC 0x0000000B
#define NDIS_MEDIUM_CO_WAN 0x0000000C
#define NDIS_MEDIUM_1394 0x0000000D
#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
#define NDIS_PACKET_TYPE_SMT 0x00000040
#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
#define NDIS_PACKET_TYPE_GROUP 0x00000100
#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200
#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400
#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800
#define NDIS_MEDIA_STATE_CONNECTED 0x00000000
#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001
#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001
#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002
#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004
#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008
#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010
#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020
#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040
#define NDIS_MAC_OPTION_RESERVED 0x80000000
#endif /* _LINUX_NDIS_H */
This diff is collapsed.
/*
* RNDIS Definitions for Remote NDIS
*
* Version: $Id: rndis.h,v 1.15 2004/03/25 21:33:46 robert Exp $
*
* Authors: Benedikt Spranger, Pengutronix
* Robert Schwebel, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2, as published by the Free Software Foundation.
*
* Due to the Remote NDIS Specification License Agreement this
* program may only be used to interact with a Microsoft Windows
* operating system or a bus/network-connected communication
* device.
*/
#ifndef _LINUX_RNDIS_H
#define _LINUX_RNDIS_H
#include "ndis.h"
#define RNDIS_MAXIMUM_FRAME_SIZE 1518
#define RNDIS_MAX_TOTAL_SIZE 1558
/* Remote NDIS Versions */
#define RNDIS_MAJOR_VERSION 1
#define RNDIS_MINOR_VERSION 0
/* Status Values */
#define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */
#define RNDIS_STATUS_FAILURE 0xC0000001U /* Unspecified error */
#define RNDIS_STATUS_INVALID_DATA 0xC0010015U /* Invalid data */
#define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBU /* Unsupported request */
#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */
#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */
/* For all not specified status messages:
* RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx
*/
/* Message Set for Connectionless (802.3) Devices */
#define REMOTE_NDIS_INIZIALIZE_MSG 0x00000002U /* Initialize device */
#define REMOTE_NDIS_HALT_MSG 0x00000003U
#define REMOTE_NDIS_QUERY_MSG 0x00000004U
#define REMOTE_NDIS_SET_MSG 0x00000005U
#define REMOTE_NDIS_RESET_MSG 0x00000006U
#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007U
#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008U
/* Message completion */
#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002U
#define REMOTE_NDIS_QUERY_CMPLT 0x80000004U
#define REMOTE_NDIS_SET_CMPLT 0x80000005U
#define REMOTE_NDIS_RESET_CMPLT 0x80000006U
#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008U
/* Device Flags */
#define RNDIS_DF_CONNECTIONLESS 0x00000001U
#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002U
#define RNDIS_MEDIUM_802_3 0x00000000U
/* supported OIDs */
static const u32 oid_supported_list [] =
{
/* mandatory general */
/* the general stuff */
OID_GEN_SUPPORTED_LIST,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_SUPPORTED,
OID_GEN_MEDIA_IN_USE,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_LINK_SPEED,
OID_GEN_TRANSMIT_BUFFER_SPACE,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_VENDOR_ID,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_VENDOR_DRIVER_VERSION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_MAC_OPTIONS,
OID_GEN_MEDIA_CONNECT_STATUS,
OID_GEN_PHYSICAL_MEDIUM,
OID_GEN_RNDIS_CONFIG_PARAMETER,
/* the statistical stuff */
OID_GEN_XMIT_OK,
OID_GEN_RCV_OK,
OID_GEN_XMIT_ERROR,
OID_GEN_RCV_ERROR,
OID_GEN_RCV_NO_BUFFER,
OID_GEN_DIRECTED_BYTES_XMIT,
OID_GEN_DIRECTED_FRAMES_XMIT,
OID_GEN_MULTICAST_BYTES_XMIT,
OID_GEN_MULTICAST_FRAMES_XMIT,
OID_GEN_BROADCAST_BYTES_XMIT,
OID_GEN_BROADCAST_FRAMES_XMIT,
OID_GEN_DIRECTED_BYTES_RCV,
OID_GEN_DIRECTED_FRAMES_RCV,
OID_GEN_MULTICAST_BYTES_RCV,
OID_GEN_MULTICAST_FRAMES_RCV,
OID_GEN_BROADCAST_BYTES_RCV,
OID_GEN_BROADCAST_FRAMES_RCV,
OID_GEN_RCV_CRC_ERROR,
OID_GEN_TRANSMIT_QUEUE_LENGTH,
/* mandatory 802.3 */
/* the general stuff */
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAC_OPTIONS,
OID_802_3_MAXIMUM_LIST_SIZE,
/* the statistical stuff */
OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
OID_802_3_XMIT_MORE_COLLISIONS
};
typedef struct rndis_init_msg_type
{
u32 MessageType;
u32 MessageLength;
u32 RequestID;
u32 MajorVersion;
u32 MinorVersion;
u32 MaxTransferSize;
} rndis_init_msg_type;
typedef struct rndis_init_cmplt_type
{
u32 MessageType;
u32 MessageLength;
u32 RequestID;
u32 Status;
u32 MajorVersion;
u32 MinorVersion;
u32 DeviceFlags;
u32 Medium;
u32 MaxPacketsPerTransfer;
u32 MaxTransferSize;
u32 PacketAlignmentFactor;
u32 AFListOffset;
u32 AFListSize;
} rndis_init_cmplt_type;
typedef struct rndis_halt_msg_type
{
u32 MessageType;
u32 MessageLength;
u32 RequestID;
} rndis_halt_msg_type;
typedef struct rndis_query_msg_type
{
u32 MessageType;
u32 MessageLength;
u32 RequestID;
u32 OID;
u32 InformationBufferLength;
u32 InformationBufferOffset;
u32 DeviceVcHandle;
} rndis_query_msg_type;
typedef struct rndis_query_cmplt_type
{
u32 MessageType;
u32 MessageLength;
u32 RequestID;
u32 Status;
u32 InformationBufferLength;
u32 InformationBufferOffset;
} rndis_query_cmplt_type;
typedef struct rndis_set_msg_type
{
u32 MessageType;
u32 MessageLength;
u32 RequestID;
u32 OID;
u32 InformationBufferLength;
u32 InformationBufferOffset;
u32 DeviceVcHandle;
} rndis_set_msg_type;
typedef struct rndis_set_cmplt_type
{
u32 MessageType;
u32 MessageLength;
u32 RequestID;
u32 Status;
} rndis_set_cmplt_type;
typedef struct rndis_reset_msg_type
{
u32 MessageType;
u32 MessageLength;
u32 Reserved;
} rndis_reset_msg_type;
typedef struct rndis_reset_cmplt_type
{
u32 MessageType;
u32 MessageLength;
u32 Status;
u32 AddressingReset;
} rndis_reset_cmplt_type;
typedef struct rndis_indicate_status_msg_type
{
u32 MessageType;
u32 MessageLength;
u32 Status;
u32 StatusBufferLength;
u32 StatusBufferOffset;
} rndis_indicate_status_msg_type;
typedef struct rndis_keepalive_msg_type
{
u32 MessageType;
u32 MessageLength;
u32 RequestID;
} rndis_keepalive_msg_type;
typedef struct rndis_keepalive_cmplt_type
{
u32 MessageType;
u32 MessageLength;
u32 RequestID;
u32 Status;
} rndis_keepalive_cmplt_type;
struct rndis_packet_msg_type
{
u32 MessageType;
u32 MessageLength;
u32 DataOffset;
u32 DataLength;
u32 OOBDataOffset;
u32 OOBDataLength;
u32 NumOOBDataElements;
u32 PerPacketInfoOffset;
u32 PerPacketInfoLength;
u32 VcHandle;
u32 Reserved;
};
struct rndis_config_parameter
{
u32 ParameterNameOffset;
u32 ParameterNameLength;
u32 ParameterType;
u32 ParameterValueOffset;
u32 ParameterValueLength;
};
/* implementation specific */
enum rndis_state
{
RNDIS_UNINITIALIZED,
RNDIS_INITIALIZED,
RNDIS_DATA_INITIALIZED,
};
typedef struct rndis_resp_t
{
struct list_head list;
u8 *buf;
u32 length;
int send;
} rndis_resp_t;
typedef struct rndis_params
{
u8 confignr;
int used;
enum rndis_state state;
u32 medium;
u32 speed;
u32 media_state;
struct net_device *dev;
struct net_device_stats *stats;
u32 vendorID;
const char *vendorDescr;
int (*ack) (struct net_device *);
struct list_head resp_queue;
} rndis_params;
/* RNDIS Message parser and other useless functions */
int rndis_msg_parser (u8 configNr, u8 *buf);
int rndis_register (int (*rndis_control_ack) (struct net_device *));
void rndis_deregister (int configNr);
int rndis_set_param_dev (u8 configNr, struct net_device *dev,
struct net_device_stats *stats);
int rndis_set_param_vendor (u8 configNr, u32 vendorID,
const char *vendorDescr);
int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed);
void rndis_add_hdr (struct sk_buff *skb);
int rndis_rm_hdr (u8 *buf, u32 *length);
u8 *rndis_get_next_response (int configNr, u32 *length);
void rndis_free_response (int configNr, u8 *buf);
int rndis_signal_connect (int configNr);
int rndis_signal_disconnect (int configNr);
int rndis_state (int configNr);
int __init rndis_init (void);
void __exit rndis_exit (void);
#endif /* _LINUX_RNDIS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment