diff mbox

[RFC,29/34] net: add Hyper-V/VMBus network protocol definitions

Message ID 20180206203048.11096-30-rkagan@virtuozzo.com (mailing list archive)
State New, archived
Headers show

Commit Message

Roman Kagan Feb. 6, 2018, 8:30 p.m. UTC
Add a header with data structures and constants defining the protocol
for communication between the guest and the hypervisor implementing the
Hyper-V/VMBus network adapter.

Mostly taken from the corresponding definitions in the Linux kernel.

TODO: move RNDIS stuff to rndis.h
Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
---
 hw/net/hvnet-proto.h | 1161 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1161 insertions(+)
 create mode 100644 hw/net/hvnet-proto.h

Comments

Paolo Bonzini Feb. 7, 2018, noon UTC | #1
On 06/02/2018 21:30, Roman Kagan wrote:
> +/* NdisInitialize message */
> +struct rndis_initialize_request {
> +    uint32_t req_id;
> +    uint32_t major_ver;
> +    uint32_t minor_ver;
> +    uint32_t max_xfer_size;
> +};
> +
> +/* Response to NdisInitialize */
> +struct rndis_initialize_complete {
> +    uint32_t req_id;
> +    uint32_t status;
> +    uint32_t major_ver;
> +    uint32_t minor_ver;
> +    uint32_t dev_flags;
> +    uint32_t medium;
> +    uint32_t max_pkt_per_msg;
> +    uint32_t max_xfer_size;
> +    uint32_t pkt_alignment_factor;
> +    uint32_t af_list_offset;
> +    uint32_t af_list_size;
> +};
> +
> +/* Call manager devices only: Information about an address family */
> +/* supported by the device is appended to the response to NdisInitialize. */
> +struct rndis_co_address_family {
> +    uint32_t address_family;
> +    uint32_t major_ver;
> +    uint32_t minor_ver;
> +};
> +
> +/* NdisHalt message */
> +struct rndis_halt_request {
> +    uint32_t req_id;
> +};
> +
> +/* NdisQueryRequest message */
> +struct rndis_query_request {
> +    uint32_t req_id;
> +    uint32_t oid;
> +    uint32_t info_buflen;
> +    uint32_t info_buf_offset;
> +    uint32_t dev_vc_handle;
> +};
> +
> +/* Response to NdisQueryRequest */
> +struct rndis_query_complete {
> +    uint32_t req_id;
> +    uint32_t status;
> +    uint32_t info_buflen;
> +    uint32_t info_buf_offset;
> +};
> +
> +/* NdisSetRequest message */
> +struct rndis_set_request {
> +    uint32_t req_id;
> +    uint32_t oid;
> +    uint32_t info_buflen;
> +    uint32_t info_buf_offset;
> +    uint32_t dev_vc_handle;
> +};
> +
> +/* Response to NdisSetRequest */
> +struct rndis_set_complete {
> +    uint32_t req_id;
> +    uint32_t status;
> +};
> +
> +/* NdisReset message */
> +struct rndis_reset_request {
> +    uint32_t reserved;
> +};
> +
> +/* Response to NdisReset */
> +struct rndis_reset_complete {
> +    uint32_t status;
> +    uint32_t addressing_reset;
> +};
> +
> +/* NdisMIndicateStatus message */
> +struct rndis_indicate_status {
> +    uint32_t status;
> +    uint32_t status_buflen;
> +    uint32_t status_buf_offset;
> +};
> +
> +/* Diagnostic information passed as the status buffer in */
> +/* struct rndis_indicate_status messages signifying error conditions. */
> +struct rndis_diagnostic_info {
> +    uint32_t diag_status;
> +    uint32_t error_offset;
> +};
> +
> +/* NdisKeepAlive message */
> +struct rndis_keepalive_request {
> +    uint32_t req_id;
> +};
> +
> +/* Response to NdisKeepAlive */
> +struct rndis_keepalive_complete {
> +    uint32_t req_id;
> +    uint32_t status;
> +};
> +

Hmm, these are a bit harder to unify with hw/usb/dev-network.c.  Still
not _that_ hard, just that the USB version has two fields for message
type/length at the beginning.  Probably worth it even if we keep two
versions of the core RNDIS code.

Paolo
Roman Kagan Feb. 7, 2018, 8:15 p.m. UTC | #2
On Wed, Feb 07, 2018 at 01:00:14PM +0100, Paolo Bonzini wrote:
> On 06/02/2018 21:30, Roman Kagan wrote:
> > +/* NdisInitialize message */
> > +struct rndis_initialize_request {
> > +    uint32_t req_id;
> > +    uint32_t major_ver;
> > +    uint32_t minor_ver;
> > +    uint32_t max_xfer_size;
> > +};
> > +
> > +/* Response to NdisInitialize */
> > +struct rndis_initialize_complete {
> > +    uint32_t req_id;
> > +    uint32_t status;
> > +    uint32_t major_ver;
> > +    uint32_t minor_ver;
> > +    uint32_t dev_flags;
> > +    uint32_t medium;
> > +    uint32_t max_pkt_per_msg;
> > +    uint32_t max_xfer_size;
> > +    uint32_t pkt_alignment_factor;
> > +    uint32_t af_list_offset;
> > +    uint32_t af_list_size;
> > +};
> > +
> > +/* Call manager devices only: Information about an address family */
> > +/* supported by the device is appended to the response to NdisInitialize. */
> > +struct rndis_co_address_family {
> > +    uint32_t address_family;
> > +    uint32_t major_ver;
> > +    uint32_t minor_ver;
> > +};
> > +
> > +/* NdisHalt message */
> > +struct rndis_halt_request {
> > +    uint32_t req_id;
> > +};
> > +
> > +/* NdisQueryRequest message */
> > +struct rndis_query_request {
> > +    uint32_t req_id;
> > +    uint32_t oid;
> > +    uint32_t info_buflen;
> > +    uint32_t info_buf_offset;
> > +    uint32_t dev_vc_handle;
> > +};
> > +
> > +/* Response to NdisQueryRequest */
> > +struct rndis_query_complete {
> > +    uint32_t req_id;
> > +    uint32_t status;
> > +    uint32_t info_buflen;
> > +    uint32_t info_buf_offset;
> > +};
> > +
> > +/* NdisSetRequest message */
> > +struct rndis_set_request {
> > +    uint32_t req_id;
> > +    uint32_t oid;
> > +    uint32_t info_buflen;
> > +    uint32_t info_buf_offset;
> > +    uint32_t dev_vc_handle;
> > +};
> > +
> > +/* Response to NdisSetRequest */
> > +struct rndis_set_complete {
> > +    uint32_t req_id;
> > +    uint32_t status;
> > +};
> > +
> > +/* NdisReset message */
> > +struct rndis_reset_request {
> > +    uint32_t reserved;
> > +};
> > +
> > +/* Response to NdisReset */
> > +struct rndis_reset_complete {
> > +    uint32_t status;
> > +    uint32_t addressing_reset;
> > +};
> > +
> > +/* NdisMIndicateStatus message */
> > +struct rndis_indicate_status {
> > +    uint32_t status;
> > +    uint32_t status_buflen;
> > +    uint32_t status_buf_offset;
> > +};
> > +
> > +/* Diagnostic information passed as the status buffer in */
> > +/* struct rndis_indicate_status messages signifying error conditions. */
> > +struct rndis_diagnostic_info {
> > +    uint32_t diag_status;
> > +    uint32_t error_offset;
> > +};
> > +
> > +/* NdisKeepAlive message */
> > +struct rndis_keepalive_request {
> > +    uint32_t req_id;
> > +};
> > +
> > +/* Response to NdisKeepAlive */
> > +struct rndis_keepalive_complete {
> > +    uint32_t req_id;
> > +    uint32_t status;
> > +};
> > +
> 
> Hmm, these are a bit harder to unify with hw/usb/dev-network.c.  Still
> not _that_ hard, just that the USB version has two fields for message
> type/length at the beginning.

This is my "fault".  At some point I got tired of this pattern so I
factored out the header and the payload.  I'll reconsider with this
unification in mind.

Roman.
Paolo Bonzini Feb. 8, 2018, 3:05 p.m. UTC | #3
On 07/02/2018 21:15, Roman Kagan wrote:
>> Hmm, these are a bit harder to unify with hw/usb/dev-network.c.  Still
>> not _that_ hard, just that the USB version has two fields for message
>> type/length at the beginning.
> This is my "fault".  At some point I got tired of this pattern so I
> factored out the header and the payload.  I'll reconsider with this
> unification in mind.

It's okay, we can also do it the other way round.

Paolo
diff mbox

Patch

diff --git a/hw/net/hvnet-proto.h b/hw/net/hvnet-proto.h
new file mode 100644
index 0000000000..1582c7e5a2
--- /dev/null
+++ b/hw/net/hvnet-proto.h
@@ -0,0 +1,1161 @@ 
+/*
+ * Hyper-V network device protocol definitions
+ *
+ * Copyright (c) 2011, Microsoft Corporation.
+ * Copyright (c) 2018 Virtuozzo International GmbH.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef _HVNET_PROTO_H_
+#define _HVNET_PROTO_H_
+
+/****
+ * c&p from linux drivers/net/hyperv/hyperv_net.h
+ ****/
+
+/* RSS related */
+#define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203  /* query only */
+#define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204  /* query and set */
+
+#define NDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88
+#define NDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89
+#define NDIS_OBJECT_TYPE_OFFLOAD	0xa7
+
+#define NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2
+#define NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2
+
+struct ndis_obj_header {
+    uint8_t type;
+    uint8_t rev;
+    uint16_t size;
+} QEMU_PACKED;
+
+/* ndis_recv_scale_cap/cap_flag */
+#define NDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x01000000
+#define NDIS_RSS_CAPS_CLASSIFICATION_AT_ISR       0x02000000
+#define NDIS_RSS_CAPS_CLASSIFICATION_AT_DPC       0x04000000
+#define NDIS_RSS_CAPS_USING_MSI_X                 0x08000000
+#define NDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS      0x10000000
+#define NDIS_RSS_CAPS_SUPPORTS_MSI_X              0x20000000
+#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4          0x00000100
+#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6          0x00000200
+#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX       0x00000400
+
+struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */
+    struct ndis_obj_header hdr;
+    uint32_t cap_flag;
+    uint32_t num_int_msg;
+    uint32_t num_recv_que;
+    uint16_t num_indirect_tabent;
+} QEMU_PACKED;
+
+
+/* ndis_recv_scale_param flags */
+#define NDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED     0x0001
+#define NDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED    0x0002
+#define NDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED       0x0004
+#define NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED     0x0008
+#define NDIS_RSS_PARAM_FLAG_DISABLE_RSS            0x0010
+
+/* Hash info bits */
+#define NDIS_HASH_FUNC_TOEPLITZ 0x00000001
+#define NDIS_HASH_IPV4          0x00000100
+#define NDIS_HASH_TCP_IPV4      0x00000200
+#define NDIS_HASH_IPV6          0x00000400
+#define NDIS_HASH_IPV6_EX       0x00000800
+#define NDIS_HASH_TCP_IPV6      0x00001000
+#define NDIS_HASH_TCP_IPV6_EX   0x00002000
+
+#define NDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4)
+#define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2   40
+
+#define ITAB_NUM 128
+
+struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */
+    struct ndis_obj_header hdr;
+
+    /* Qualifies the rest of the information */
+    uint16_t flag;
+
+    /* The base CPU number to do receive processing. not used */
+    uint16_t base_cpu_number;
+
+    /* This describes the hash function and type being enabled */
+    uint32_t hashinfo;
+
+    /* The size of indirection table array */
+    uint16_t indirect_tabsize;
+
+    /* The offset of the indirection table from the beginning of this
+     * structure
+     */
+    uint32_t indirect_taboffset;
+
+    /* The size of the hash secret key */
+    uint16_t hashkey_size;
+
+    /* The offset of the secret key from the beginning of this structure */
+    uint32_t kashkey_offset;
+
+    uint32_t processor_masks_offset;
+    uint32_t num_processor_masks;
+    uint32_t processor_masks_entry_size;
+};
+
+/* Fwd declaration */
+struct ndis_tcp_ip_checksum_info;
+struct ndis_pkt_8021q_info;
+
+/*
+ * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
+ * within the RNDIS
+ *
+ * The size of this structure is less than 48 bytes and we can now
+ * place this structure in the skb->cb field.
+ */
+struct hv_netvsc_packet {
+    /* Bookkeeping stuff */
+    uint8_t cp_partial; /* partial copy into send buffer */
+
+    uint8_t rmsg_size; /* RNDIS header and PPI size */
+    uint8_t rmsg_pgcnt; /* page count of RNDIS header and PPI */
+    uint8_t page_buf_cnt;
+
+    uint16_t q_idx;
+    uint16_t total_packets;
+
+    uint32_t total_bytes;
+    uint32_t send_buf_index;
+    uint32_t total_data_buflen;
+};
+
+enum rndis_device_state {
+    RNDIS_DEV_UNINITIALIZED = 0,
+    RNDIS_DEV_INITIALIZING,
+    RNDIS_DEV_INITIALIZED,
+    RNDIS_DEV_DATAINITIALIZED,
+};
+
+#define NETVSC_HASH_KEYLEN 40
+
+#define NVSP_INVALID_PROTOCOL_VERSION	((uint32_t)0xFFFFFFFF)
+
+#define NVSP_PROTOCOL_VERSION_1		2
+#define NVSP_PROTOCOL_VERSION_2		0x30002
+#define NVSP_PROTOCOL_VERSION_4		0x40000
+#define NVSP_PROTOCOL_VERSION_5		0x50000
+
+enum {
+    NVSP_MSG_TYPE_NONE = 0,
+
+    /* Init Messages */
+    NVSP_MSG_TYPE_INIT			= 1,
+    NVSP_MSG_TYPE_INIT_COMPLETE		= 2,
+
+    NVSP_VERSION_MSG_START			= 100,
+
+    /* Version 1 Messages */
+    NVSP_MSG1_TYPE_SEND_NDIS_VER		= NVSP_VERSION_MSG_START,
+
+    NVSP_MSG1_TYPE_SEND_RECV_BUF,
+    NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE,
+    NVSP_MSG1_TYPE_REVOKE_RECV_BUF,
+
+    NVSP_MSG1_TYPE_SEND_SEND_BUF,
+    NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE,
+    NVSP_MSG1_TYPE_REVOKE_SEND_BUF,
+
+    NVSP_MSG1_TYPE_SEND_RNDIS_PKT,
+    NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE,
+
+    /* Version 2 messages */
+    NVSP_MSG2_TYPE_SEND_CHIMNEY_DELEGATED_BUF,
+    NVSP_MSG2_TYPE_SEND_CHIMNEY_DELEGATED_BUF_COMP,
+    NVSP_MSG2_TYPE_REVOKE_CHIMNEY_DELEGATED_BUF,
+
+    NVSP_MSG2_TYPE_RESUME_CHIMNEY_RX_INDICATION,
+
+    NVSP_MSG2_TYPE_TERMINATE_CHIMNEY,
+    NVSP_MSG2_TYPE_TERMINATE_CHIMNEY_COMP,
+
+    NVSP_MSG2_TYPE_INDICATE_CHIMNEY_EVENT,
+
+    NVSP_MSG2_TYPE_SEND_CHIMNEY_PKT,
+    NVSP_MSG2_TYPE_SEND_CHIMNEY_PKT_COMP,
+
+    NVSP_MSG2_TYPE_POST_CHIMNEY_RECV_REQ,
+    NVSP_MSG2_TYPE_POST_CHIMNEY_RECV_REQ_COMP,
+
+    NVSP_MSG2_TYPE_ALLOC_RXBUF,
+    NVSP_MSG2_TYPE_ALLOC_RXBUF_COMP,
+
+    NVSP_MSG2_TYPE_FREE_RXBUF,
+
+    NVSP_MSG2_TYPE_SEND_VMQ_RNDIS_PKT,
+    NVSP_MSG2_TYPE_SEND_VMQ_RNDIS_PKT_COMP,
+
+    NVSP_MSG2_TYPE_SEND_NDIS_CONFIG,
+
+    NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE,
+    NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP,
+
+    NVSP_MSG2_MAX = NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP,
+
+    /* Version 4 messages */
+    NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION,
+    NVSP_MSG4_TYPE_SWITCH_DATA_PATH,
+    NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED,
+
+    NVSP_MSG4_MAX = NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED,
+
+    /* Version 5 messages */
+    NVSP_MSG5_TYPE_OID_QUERY_EX,
+    NVSP_MSG5_TYPE_OID_QUERY_EX_COMP,
+    NVSP_MSG5_TYPE_SUBCHANNEL,
+    NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE,
+
+    NVSP_MSG5_MAX = NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE,
+};
+
+enum {
+    NVSP_STAT_NONE = 0,
+    NVSP_STAT_SUCCESS,
+    NVSP_STAT_FAIL,
+    NVSP_STAT_PROTOCOL_TOO_NEW,
+    NVSP_STAT_PROTOCOL_TOO_OLD,
+    NVSP_STAT_INVALID_RNDIS_PKT,
+    NVSP_STAT_BUSY,
+    NVSP_STAT_PROTOCOL_UNSUPPORTED,
+    NVSP_STAT_MAX,
+};
+
+struct nvsp_msg_header {
+    uint32_t msg_type;
+};
+
+/* Init Messages */
+
+/*
+ * This message is used by the VSC to initialize the channel after the channels
+ * has been opened. This message should never include anything other then
+ * versioning (i.e. this message will be the same for ever).
+ */
+struct nvsp_msg_init {
+    uint32_t min_protocol_ver;
+    uint32_t max_protocol_ver;
+} QEMU_PACKED;
+
+/*
+ * This message is used by the VSP to complete the initialization of the
+ * channel. This message should never include anything other then versioning
+ * (i.e. this message will be the same for ever).
+ */
+struct nvsp_msg_init_complete {
+    uint32_t negotiated_protocol_ver;
+    uint32_t max_mdl_chain_len;
+    uint32_t status;
+};
+
+/* Version 1 Messages */
+
+/*
+ * This message is used by the VSC to send the NDIS version to the VSP. The VSP
+ * can use this information when handling OIDs sent by the VSC.
+ */
+struct nvsp1_msg_ndis_ver {
+    uint32_t ndis_major_ver;
+    uint32_t ndis_minor_ver;
+} QEMU_PACKED;
+
+/*
+ * This message is used by the VSC to send a receive buffer to the VSP. The VSP
+ * can then use the receive buffer to send data to the VSC.
+ */
+struct nvsp1_msg_rcvbuf {
+    uint32_t gpadl_handle;
+    uint16_t id;
+} QEMU_PACKED;
+
+struct nvsp1_rcvbuf_section {
+    uint32_t offset;
+    uint32_t sub_alloc_size;
+    uint32_t num_sub_allocs;
+    uint32_t end_offset;
+} QEMU_PACKED;
+
+/*
+ * This message is used by the VSP to acknowledge a receive buffer send by the
+ * VSC. This message must be sent by the VSP before the VSP uses the receive
+ * buffer.
+ */
+struct nvsp1_msg_rcvbuf_complete {
+    uint32_t status;
+    uint32_t num_sections;
+
+    /*
+     * The receive buffer is split into two parts, a large suballocation
+     * section and a small suballocation section. These sections are then
+     * suballocated by a certain size.
+     */
+
+    /*
+     * For example, the following break up of the receive buffer has 6
+     * large suballocations and 10 small suballocations.
+     */
+
+    /*
+     * |            Large Section          |  |   Small Section   |
+     * ------------------------------------------------------------
+     * |     |     |     |     |     |     |  | | | | | | | | | | |
+     * |                                      |
+     *  LargeOffset                            SmallOffset
+     */
+
+    struct nvsp1_rcvbuf_section sections[1];
+} QEMU_PACKED;
+
+/*
+ * This message is sent by the VSC to revoke the receive buffer.  After the VSP
+ * completes this transaction, the vsp should never use the receive buffer
+ * again.
+ */
+struct nvsp1_msg_revoke_rcvbuf {
+    uint16_t id;
+};
+
+/*
+ * This message is used by the VSC to send a send buffer to the VSP. The VSC
+ * can then use the send buffer to send data to the VSP.
+ */
+struct nvsp1_msg_sndbuf {
+    uint32_t gpadl_handle;
+    uint16_t id;
+} QEMU_PACKED;
+
+/*
+ * This message is used by the VSP to acknowledge a send buffer sent by the
+ * VSC. This message must be sent by the VSP before the VSP uses the sent
+ * buffer.
+ */
+struct nvsp1_msg_sndbuf_complete {
+    uint32_t status;
+
+    /*
+     * The VSC gets to choose the size of the send buffer and the VSP gets
+     * to choose the sections size of the buffer.  This was done to enable
+     * dynamic reconfigurations when the cost of GPA-direct buffers
+     * decreases.
+     */
+    uint32_t section_size;
+} QEMU_PACKED;
+
+/*
+ * This message is sent by the VSC to revoke the send buffer.  After the VSP
+ * completes this transaction, the vsp should never use the send buffer again.
+ */
+struct nvsp1_msg_revoke_sndbuf {
+    uint16_t id;
+};
+
+/*
+ * This message is used by both the VSP and the VSC to send a RNDIS message to
+ * the opposite channel endpoint.
+ */
+struct nvsp1_msg_rndis_pkt {
+    /*
+     * This field is specified by RNDIS. They assume there's two different
+     * channels of communication. However, the Network VSP only has one.
+     * Therefore, the channel travels with the RNDIS packet.
+     */
+    uint32_t channel_type;
+
+    /*
+     * This field is used to send part or all of the data through a send
+     * buffer. This values specifies an index into the send buffer. If the
+     * index is 0xFFFFFFFF, then the send buffer is not being used and all
+     * of the data was sent through other VMBus mechanisms.
+     */
+    uint32_t send_buf_section_index;
+    uint32_t send_buf_section_size;
+} QEMU_PACKED;
+
+/*
+ * This message is used by both the VSP and the VSC to complete a RNDIS message
+ * to the opposite channel endpoint. At this point, the initiator of this
+ * message cannot use any resources associated with the original RNDIS packet.
+ */
+struct nvsp1_msg_rndis_pkt_complete {
+    uint32_t status;
+};
+
+/*
+ * Network VSP protocol version 2 messages:
+ */
+struct nvsp2_vsc_capability {
+    union {
+        uint64_t data;
+        struct {
+            uint64_t vmq:1;
+            uint64_t chimney:1;
+            uint64_t sriov:1;
+            uint64_t ieee8021q:1;
+            uint64_t correlation_id:1;
+            uint64_t teaming:1;
+        };
+    };
+} QEMU_PACKED;
+
+struct nvsp2_send_ndis_config {
+    uint32_t mtu;
+    uint32_t reserved;
+    struct nvsp2_vsc_capability capability;
+} QEMU_PACKED;
+
+/* Allocate receive buffer */
+struct nvsp2_alloc_rxbuf {
+    /* Allocation ID to match the allocation request and response */
+    uint32_t alloc_id;
+
+    /* Length of the VM shared memory receive buffer that needs to
+     * be allocated
+     */
+    uint32_t len;
+} QEMU_PACKED;
+
+/* Allocate receive buffer complete */
+struct nvsp2_alloc_rxbuf_comp {
+    /* The NDIS_STATUS code for buffer allocation */
+    uint32_t status;
+
+    uint32_t alloc_id;
+
+    /* GPADL handle for the allocated receive buffer */
+    uint32_t gpadl_handle;
+
+    /* Receive buffer ID */
+    uint64_t recv_buf_id;
+} QEMU_PACKED;
+
+struct nvsp2_free_rxbuf {
+    uint64_t recv_buf_id;
+} QEMU_PACKED;
+
+struct nvsp4_send_vf_association {
+    /* 1: allocated, serial number is valid. 0: not allocated */
+    uint32_t allocated;
+
+    /* Serial number of the VF to team with */
+    uint32_t serial;
+} QEMU_PACKED;
+
+enum nvsp_vm_datapath {
+    NVSP_DATAPATH_SYNTHETIC = 0,
+    NVSP_DATAPATH_VF,
+    NVSP_DATAPATH_MAX
+};
+
+struct nvsp4_sw_datapath {
+    uint32_t active_datapath; /* active data path in VM */
+} QEMU_PACKED;
+
+enum nvsp_subchannel_operation {
+    NVSP_SUBCHANNEL_NONE = 0,
+    NVSP_SUBCHANNEL_ALLOCATE,
+    NVSP_SUBCHANNEL_MAX
+};
+
+struct nvsp5_subchannel_request {
+    uint32_t op;
+    uint32_t num_subchannels;
+} QEMU_PACKED;
+
+struct nvsp5_subchannel_complete {
+    uint32_t status;
+    uint32_t num_subchannels; /* Actual number of subchannels allocated */
+} QEMU_PACKED;
+
+struct nvsp5_send_indirect_table {
+    /* The number of entries in the send indirection table */
+    uint32_t count;
+
+    /* The offset of the send indirection table from top of this struct.
+     * The send indirection table tells which channel to put the send
+     * traffic on. Each entry is a channel number.
+     */
+    uint32_t offset;
+} QEMU_PACKED;
+
+union nvsp_all_messages {
+    struct nvsp_msg_init init;
+    struct nvsp_msg_init_complete init_complete;
+
+    struct nvsp1_msg_ndis_ver send_ndis_ver;
+    struct nvsp1_msg_rcvbuf send_recv_buf;
+    struct nvsp1_msg_rcvbuf_complete send_recv_buf_complete;
+    struct nvsp1_msg_revoke_rcvbuf revoke_recv_buf;
+    struct nvsp1_msg_sndbuf send_send_buf;
+    struct nvsp1_msg_sndbuf_complete send_send_buf_complete;
+    struct nvsp1_msg_revoke_sndbuf revoke_send_buf;
+    struct nvsp1_msg_rndis_pkt send_rndis_pkt;
+    struct nvsp1_msg_rndis_pkt_complete send_rndis_pkt_complete;
+
+    struct nvsp2_send_ndis_config send_ndis_config;
+    struct nvsp2_alloc_rxbuf alloc_rxbuf;
+    struct nvsp2_alloc_rxbuf_comp alloc_rxbuf_comp;
+    struct nvsp2_free_rxbuf free_rxbuf;
+
+    struct nvsp4_send_vf_association vf_assoc;
+    struct nvsp4_sw_datapath active_dp;
+
+    struct nvsp5_subchannel_request subchn_req;
+    struct nvsp5_subchannel_complete subchn_comp;
+    struct nvsp5_send_indirect_table send_table;
+} QEMU_PACKED;
+
+/* ALL Messages */
+struct nvsp_msg {
+    struct nvsp_msg_header hdr;
+    union nvsp_all_messages msg;
+} QEMU_PACKED;
+
+
+#define NETVSC_MTU 65535
+#define NETVSC_MTU_MIN ETH_MIN_MTU
+
+#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024*16)	/* 16MB */
+#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY	(1024*1024*15)  /* 15MB */
+#define NETVSC_SEND_BUFFER_SIZE			(1024 * 1024 * 15)   /* 15MB */
+#define NETVSC_INVALID_INDEX			-1
+
+
+#define NETVSC_RECEIVE_BUFFER_ID		0xcafe
+#define NETVSC_SEND_BUFFER_ID			0
+
+#define NETVSC_PACKET_SIZE                      4096
+
+#define VRSS_SEND_TAB_SIZE 16  /* must be power of 2 */
+#define VRSS_CHANNEL_MAX 64
+#define VRSS_CHANNEL_DEFAULT 8
+
+#define RNDIS_MAX_PKT_DEFAULT 8
+#define RNDIS_PKT_ALIGN_DEFAULT 8
+
+/* Netvsc Receive Slots Max */
+#define NETVSC_RECVSLOT_MAX (NETVSC_RECEIVE_BUFFER_SIZE / ETH_DATA_LEN + 1)
+
+/* NdisInitialize message */
+struct rndis_initialize_request {
+    uint32_t req_id;
+    uint32_t major_ver;
+    uint32_t minor_ver;
+    uint32_t max_xfer_size;
+};
+
+/* Response to NdisInitialize */
+struct rndis_initialize_complete {
+    uint32_t req_id;
+    uint32_t status;
+    uint32_t major_ver;
+    uint32_t minor_ver;
+    uint32_t dev_flags;
+    uint32_t medium;
+    uint32_t max_pkt_per_msg;
+    uint32_t max_xfer_size;
+    uint32_t pkt_alignment_factor;
+    uint32_t af_list_offset;
+    uint32_t af_list_size;
+};
+
+/* Call manager devices only: Information about an address family */
+/* supported by the device is appended to the response to NdisInitialize. */
+struct rndis_co_address_family {
+    uint32_t address_family;
+    uint32_t major_ver;
+    uint32_t minor_ver;
+};
+
+/* NdisHalt message */
+struct rndis_halt_request {
+    uint32_t req_id;
+};
+
+/* NdisQueryRequest message */
+struct rndis_query_request {
+    uint32_t req_id;
+    uint32_t oid;
+    uint32_t info_buflen;
+    uint32_t info_buf_offset;
+    uint32_t dev_vc_handle;
+};
+
+/* Response to NdisQueryRequest */
+struct rndis_query_complete {
+    uint32_t req_id;
+    uint32_t status;
+    uint32_t info_buflen;
+    uint32_t info_buf_offset;
+};
+
+/* NdisSetRequest message */
+struct rndis_set_request {
+    uint32_t req_id;
+    uint32_t oid;
+    uint32_t info_buflen;
+    uint32_t info_buf_offset;
+    uint32_t dev_vc_handle;
+};
+
+/* Response to NdisSetRequest */
+struct rndis_set_complete {
+    uint32_t req_id;
+    uint32_t status;
+};
+
+/* NdisReset message */
+struct rndis_reset_request {
+    uint32_t reserved;
+};
+
+/* Response to NdisReset */
+struct rndis_reset_complete {
+    uint32_t status;
+    uint32_t addressing_reset;
+};
+
+/* NdisMIndicateStatus message */
+struct rndis_indicate_status {
+    uint32_t status;
+    uint32_t status_buflen;
+    uint32_t status_buf_offset;
+};
+
+/* Diagnostic information passed as the status buffer in */
+/* struct rndis_indicate_status messages signifying error conditions. */
+struct rndis_diagnostic_info {
+    uint32_t diag_status;
+    uint32_t error_offset;
+};
+
+/* NdisKeepAlive message */
+struct rndis_keepalive_request {
+    uint32_t req_id;
+};
+
+/* Response to NdisKeepAlive */
+struct rndis_keepalive_complete {
+    uint32_t req_id;
+    uint32_t status;
+};
+
+/*
+ * Data message. All Offset fields contain byte offsets from the beginning of
+ * struct rndis_packet. All Length fields are in bytes.  VcHandle is set
+ * to 0 for connectionless data, otherwise it contains the VC handle.
+ */
+struct rndis_packet {
+    uint32_t data_offset;
+    uint32_t data_len;
+    uint32_t oob_data_offset;
+    uint32_t oob_data_len;
+    uint32_t num_oob_data_elements;
+    uint32_t per_pkt_info_offset;
+    uint32_t per_pkt_info_len;
+    uint32_t vc_handle;
+    uint32_t reserved;
+};
+
+/* Optional Out of Band data associated with a Data message. */
+struct rndis_oobd {
+    uint32_t size;
+    uint32_t type;
+    uint32_t class_info_offset;
+};
+
+/* Packet extension field contents associated with a Data message. */
+struct rndis_per_packet_info {
+    uint32_t size;
+    uint32_t type;
+    uint32_t ppi_offset;
+};
+
+enum ndis_per_pkt_info_type {
+    TCPIP_CHKSUM_PKTINFO,
+    IPSEC_PKTINFO,
+    TCP_LARGESEND_PKTINFO,
+    CLASSIFICATION_HANDLE_PKTINFO,
+    NDIS_RESERVED,
+    SG_LIST_PKTINFO,
+    IEEE_8021Q_INFO,
+    ORIGINAL_PKTINFO,
+    PACKET_CANCEL_ID,
+    NBL_HASH_VALUE = PACKET_CANCEL_ID,
+    ORIGINAL_NET_BUFLIST,
+    CACHED_NET_BUFLIST,
+    SHORT_PKT_PADINFO,
+    MAX_PER_PKT_INFO
+};
+
+struct ndis_pkt_8021q_info {
+    union {
+        struct {
+            uint32_t pri:3; /* User Priority */
+            uint32_t cfi:1; /* Canonical Format ID */
+            uint32_t vlanid:12; /* VLAN ID */
+            uint32_t reserved:16;
+        };
+        uint32_t value;
+    };
+};
+
+struct ndis_object_header {
+    uint8_t type;
+    uint8_t revision;
+    uint16_t size;
+};
+
+#define NDIS_OBJECT_TYPE_DEFAULT	0x80
+#define NDIS_OFFLOAD_PARAMETERS_REVISION_3 3
+#define NDIS_OFFLOAD_PARAMETERS_REVISION_2 2
+#define NDIS_OFFLOAD_PARAMETERS_REVISION_1 1
+
+#define NDIS_OFFLOAD_PARAMETERS_NO_CHANGE 0
+#define NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED 1
+#define NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED  2
+#define NDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED  2
+#define NDIS_OFFLOAD_PARAMETERS_RSC_DISABLED 1
+#define NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED 2
+#define NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED 1
+#define NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED 2
+#define NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED 3
+#define NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED 4
+
+#define NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE	1
+#define NDIS_TCP_LARGE_SEND_OFFLOAD_IPV4	0
+#define NDIS_TCP_LARGE_SEND_OFFLOAD_IPV6	1
+
+#define VERSION_4_OFFLOAD_SIZE			22
+/*
+ * New offload OIDs for NDIS 6
+ */
+#define OID_TCP_OFFLOAD_CURRENT_CONFIG 0xFC01020B /* query only */
+#define OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C		/* set only */
+#define OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES 0xFC01020D/* query only */
+#define OID_TCP_CONNECTION_OFFLOAD_CURRENT_CONFIG 0xFC01020E /* query only */
+#define OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES 0xFC01020F /* query */
+#define OID_OFFLOAD_ENCAPSULATION 0x0101010A /* set/query */
+
+/*
+ * OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES
+ * ndis_type: NDIS_OBJTYPE_OFFLOAD
+ */
+
+#define	NDIS_OFFLOAD_ENCAP_NONE		0x0000
+#define	NDIS_OFFLOAD_ENCAP_NULL		0x0001
+#define	NDIS_OFFLOAD_ENCAP_8023		0x0002
+#define	NDIS_OFFLOAD_ENCAP_8023PQ	0x0004
+#define	NDIS_OFFLOAD_ENCAP_8023PQ_OOB	0x0008
+#define	NDIS_OFFLOAD_ENCAP_RFC1483	0x0010
+
+struct ndis_csum_offload {
+    uint32_t	ip4_txenc;
+    uint32_t	ip4_txcsum;
+#define	NDIS_TXCSUM_CAP_IP4OPT		0x001
+#define	NDIS_TXCSUM_CAP_TCP4OPT		0x004
+#define	NDIS_TXCSUM_CAP_TCP4		0x010
+#define	NDIS_TXCSUM_CAP_UDP4		0x040
+#define	NDIS_TXCSUM_CAP_IP4		0x100
+
+#define NDIS_TXCSUM_ALL_TCP4	(NDIS_TXCSUM_CAP_TCP4 | NDIS_TXCSUM_CAP_TCP4OPT)
+
+    uint32_t	ip4_rxenc;
+    uint32_t	ip4_rxcsum;
+#define	NDIS_RXCSUM_CAP_IP4OPT		0x001
+#define	NDIS_RXCSUM_CAP_TCP4OPT		0x004
+#define	NDIS_RXCSUM_CAP_TCP4		0x010
+#define	NDIS_RXCSUM_CAP_UDP4		0x040
+#define	NDIS_RXCSUM_CAP_IP4		0x100
+    uint32_t	ip6_txenc;
+    uint32_t	ip6_txcsum;
+#define	NDIS_TXCSUM_CAP_IP6EXT		0x001
+#define	NDIS_TXCSUM_CAP_TCP6OPT		0x004
+#define	NDIS_TXCSUM_CAP_TCP6		0x010
+#define	NDIS_TXCSUM_CAP_UDP6		0x040
+    uint32_t	ip6_rxenc;
+    uint32_t	ip6_rxcsum;
+#define	NDIS_RXCSUM_CAP_IP6EXT		0x001
+#define	NDIS_RXCSUM_CAP_TCP6OPT		0x004
+#define	NDIS_RXCSUM_CAP_TCP6		0x010
+#define	NDIS_RXCSUM_CAP_UDP6		0x040
+
+#define NDIS_TXCSUM_ALL_TCP6	(NDIS_TXCSUM_CAP_TCP6 |		\
+                                 NDIS_TXCSUM_CAP_TCP6OPT |	\
+                                 NDIS_TXCSUM_CAP_IP6EXT)
+};
+
+struct ndis_lsov1_offload {
+    uint32_t	encap;
+    uint32_t	maxsize;
+    uint32_t	minsegs;
+    uint32_t	opts;
+};
+
+struct ndis_ipsecv1_offload {
+    uint32_t	encap;
+    uint32_t	ah_esp;
+    uint32_t	xport_tun;
+    uint32_t	ip4_opts;
+    uint32_t	flags;
+    uint32_t	ip4_ah;
+    uint32_t	ip4_esp;
+};
+
+struct ndis_lsov2_offload {
+    uint32_t	ip4_encap;
+    uint32_t	ip4_maxsz;
+    uint32_t	ip4_minsg;
+    uint32_t	ip6_encap;
+    uint32_t	ip6_maxsz;
+    uint32_t	ip6_minsg;
+    uint32_t	ip6_opts;
+#define	NDIS_LSOV2_CAP_IP6EXT		0x001
+#define	NDIS_LSOV2_CAP_TCP6OPT		0x004
+
+#define NDIS_LSOV2_CAP_IP6		(NDIS_LSOV2_CAP_IP6EXT | \
+                                         NDIS_LSOV2_CAP_TCP6OPT)
+};
+
+struct ndis_ipsecv2_offload {
+    uint32_t	encap;
+    uint16_t	ip6;
+    uint16_t	ip4opt;
+    uint16_t	ip6ext;
+    uint16_t	ah;
+    uint16_t	esp;
+    uint16_t	ah_esp;
+    uint16_t	xport;
+    uint16_t	tun;
+    uint16_t	xport_tun;
+    uint16_t	lso;
+    uint16_t	extseq;
+    uint32_t	udp_esp;
+    uint32_t	auth;
+    uint32_t	crypto;
+    uint32_t	sa_caps;
+};
+
+struct ndis_rsc_offload {
+    uint16_t	ip4;
+    uint16_t	ip6;
+};
+
+struct ndis_encap_offload {
+    uint32_t	flags;
+    uint32_t	maxhdr;
+};
+
+struct ndis_offload {
+    struct ndis_object_header	header;
+    struct ndis_csum_offload	csum;
+    struct ndis_lsov1_offload	lsov1;
+    struct ndis_ipsecv1_offload	ipsecv1;
+    struct ndis_lsov2_offload	lsov2;
+    uint32_t				flags;
+    /* NDIS >= 6.1 */
+    struct ndis_ipsecv2_offload	ipsecv2;
+    /* NDIS >= 6.30 */
+    struct ndis_rsc_offload		rsc;
+    struct ndis_encap_offload	encap_gre;
+};
+
+#define	NDIS_OFFLOAD_SIZE		sizeof(struct ndis_offload)
+#define	NDIS_OFFLOAD_SIZE_6_0		offsetof(struct ndis_offload, ipsecv2)
+#define	NDIS_OFFLOAD_SIZE_6_1		offsetof(struct ndis_offload, rsc)
+
+struct ndis_offload_params {
+    struct ndis_object_header header;
+    uint8_t ip_v4_csum;
+    uint8_t tcp_ip_v4_csum;
+    uint8_t udp_ip_v4_csum;
+    uint8_t tcp_ip_v6_csum;
+    uint8_t udp_ip_v6_csum;
+    uint8_t lso_v1;
+    uint8_t ip_sec_v1;
+    uint8_t lso_v2_ipv4;
+    uint8_t lso_v2_ipv6;
+    uint8_t tcp_connection_ip_v4;
+    uint8_t tcp_connection_ip_v6;
+    uint32_t flags;
+    uint8_t ip_sec_v2;
+    uint8_t ip_sec_v2_ip_v4;
+    struct {
+        uint8_t rsc_ip_v4;
+        uint8_t rsc_ip_v6;
+    };
+    struct {
+        uint8_t encapsulated_packet_task_offload;
+        uint8_t encapsulation_types;
+    };
+};
+
+struct ndis_tcp_ip_checksum_info {
+    union {
+        struct {
+            uint32_t is_ipv4:1;
+            uint32_t is_ipv6:1;
+            uint32_t tcp_checksum:1;
+            uint32_t udp_checksum:1;
+            uint32_t ip_header_checksum:1;
+            uint32_t reserved:11;
+            uint32_t tcp_header_offset:10;
+        } transmit;
+        struct {
+            uint32_t tcp_checksum_failed:1;
+            uint32_t udp_checksum_failed:1;
+            uint32_t ip_checksum_failed:1;
+            uint32_t tcp_checksum_succeeded:1;
+            uint32_t udp_checksum_succeeded:1;
+            uint32_t ip_checksum_succeeded:1;
+            uint32_t loopback:1;
+            uint32_t tcp_checksum_value_invalid:1;
+            uint32_t ip_checksum_value_invalid:1;
+        } receive;
+        uint32_t  value;
+    };
+};
+
+struct ndis_tcp_lso_info {
+    union {
+        struct {
+            uint32_t unused:30;
+            uint32_t type:1;
+            uint32_t reserved2:1;
+        } transmit;
+        struct {
+            uint32_t mss:20;
+            uint32_t tcp_header_offset:10;
+            uint32_t type:1;
+            uint32_t reserved2:1;
+        } lso_v1_transmit;
+        struct {
+            uint32_t tcp_payload:30;
+            uint32_t type:1;
+            uint32_t reserved2:1;
+        } lso_v1_transmit_complete;
+        struct {
+            uint32_t mss:20;
+            uint32_t tcp_header_offset:10;
+            uint32_t type:1;
+            uint32_t ip_version:1;
+        } lso_v2_transmit;
+        struct {
+            uint32_t reserved:30;
+            uint32_t type:1;
+            uint32_t reserved2:1;
+        } lso_v2_transmit_complete;
+        uint32_t  value;
+    };
+};
+
+#define NDIS_VLAN_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
+                            sizeof(struct ndis_pkt_8021q_info))
+
+#define NDIS_CSUM_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
+                            sizeof(struct ndis_tcp_ip_checksum_info))
+
+#define NDIS_LSO_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
+                           sizeof(struct ndis_tcp_lso_info))
+
+#define NDIS_HASH_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
+                            sizeof(uint32_t))
+
+/* Total size of all PPI data */
+#define NDIS_ALL_PPI_SIZE (NDIS_VLAN_PPI_SIZE + NDIS_CSUM_PPI_SIZE + \
+                           NDIS_LSO_PPI_SIZE + NDIS_HASH_PPI_SIZE)
+
+/* Format of Information buffer passed in a SetRequest for the OID */
+/* OID_GEN_RNDIS_CONFIG_PARAMETER. */
+struct rndis_config_parameter_info {
+    uint32_t parameter_name_offset;
+    uint32_t parameter_name_length;
+    uint32_t parameter_type;
+    uint32_t parameter_value_offset;
+    uint32_t parameter_value_length;
+};
+
+/* Values for ParameterType in struct rndis_config_parameter_info */
+#define RNDIS_CONFIG_PARAM_TYPE_INTEGER     0
+#define RNDIS_CONFIG_PARAM_TYPE_STRING      2
+
+/* CONDIS Miniport messages for connection oriented devices */
+/* that do not implement a call manager. */
+
+/* CoNdisMiniportCreateVc message */
+struct rcondis_mp_create_vc {
+    uint32_t req_id;
+    uint32_t ndis_vc_handle;
+};
+
+/* Response to CoNdisMiniportCreateVc */
+struct rcondis_mp_create_vc_complete {
+    uint32_t req_id;
+    uint32_t dev_vc_handle;
+    uint32_t status;
+};
+
+/* CoNdisMiniportDeleteVc message */
+struct rcondis_mp_delete_vc {
+    uint32_t req_id;
+    uint32_t dev_vc_handle;
+};
+
+/* Response to CoNdisMiniportDeleteVc */
+struct rcondis_mp_delete_vc_complete {
+    uint32_t req_id;
+    uint32_t status;
+};
+
+/* CoNdisMiniportQueryRequest message */
+struct rcondis_mp_query_request {
+    uint32_t req_id;
+    uint32_t request_type;
+    uint32_t oid;
+    uint32_t dev_vc_handle;
+    uint32_t info_buflen;
+    uint32_t info_buf_offset;
+};
+
+/* CoNdisMiniportSetRequest message */
+struct rcondis_mp_set_request {
+    uint32_t req_id;
+    uint32_t request_type;
+    uint32_t oid;
+    uint32_t dev_vc_handle;
+    uint32_t info_buflen;
+    uint32_t info_buf_offset;
+};
+
+/* CoNdisIndicateStatus message */
+struct rcondis_indicate_status {
+    uint32_t ndis_vc_handle;
+    uint32_t status;
+    uint32_t status_buflen;
+    uint32_t status_buf_offset;
+};
+
+/* CONDIS Call/VC parameters */
+struct rcondis_specific_parameters {
+    uint32_t parameter_type;
+    uint32_t parameter_length;
+    uint32_t parameter_lffset;
+};
+
+struct rcondis_media_parameters {
+    uint32_t flags;
+    uint32_t reserved1;
+    uint32_t reserved2;
+    struct rcondis_specific_parameters media_specific;
+};
+
+struct rndis_flowspec {
+    uint32_t token_rate;
+    uint32_t token_bucket_size;
+    uint32_t peak_bandwidth;
+    uint32_t latency;
+    uint32_t delay_variation;
+    uint32_t service_type;
+    uint32_t max_sdu_size;
+    uint32_t minimum_policed_size;
+};
+
+struct rcondis_call_manager_parameters {
+    struct rndis_flowspec transmit;
+    struct rndis_flowspec receive;
+    struct rcondis_specific_parameters call_mgr_specific;
+};
+
+/* CoNdisMiniportActivateVc message */
+struct rcondis_mp_activate_vc_request {
+    uint32_t req_id;
+    uint32_t flags;
+    uint32_t dev_vc_handle;
+    uint32_t media_params_offset;
+    uint32_t media_params_length;
+    uint32_t call_mgr_params_offset;
+    uint32_t call_mgr_params_length;
+};
+
+/* Response to CoNdisMiniportActivateVc */
+struct rcondis_mp_activate_vc_complete {
+    uint32_t req_id;
+    uint32_t status;
+};
+
+/* CoNdisMiniportDeactivateVc message */
+struct rcondis_mp_deactivate_vc_request {
+    uint32_t req_id;
+    uint32_t flags;
+    uint32_t dev_vc_handle;
+};
+
+/* Response to CoNdisMiniportDeactivateVc */
+struct rcondis_mp_deactivate_vc_complete {
+    uint32_t req_id;
+    uint32_t status;
+};
+
+
+/* union with all of the RNDIS messages */
+union rndis_message_container {
+    struct rndis_packet pkt;
+    struct rndis_initialize_request init_req;
+    struct rndis_halt_request halt_req;
+    struct rndis_query_request query_req;
+    struct rndis_set_request set_req;
+    struct rndis_reset_request reset_req;
+    struct rndis_keepalive_request keep_alive_req;
+    struct rndis_indicate_status indicate_status;
+    struct rndis_initialize_complete init_complete;
+    struct rndis_query_complete query_complete;
+    struct rndis_set_complete set_complete;
+    struct rndis_reset_complete reset_complete;
+    struct rndis_keepalive_complete keep_alive_complete;
+    struct rcondis_mp_create_vc co_miniport_create_vc;
+    struct rcondis_mp_delete_vc co_miniport_delete_vc;
+    struct rcondis_indicate_status co_indicate_status;
+    struct rcondis_mp_activate_vc_request co_miniport_activate_vc;
+    struct rcondis_mp_deactivate_vc_request co_miniport_deactivate_vc;
+    struct rcondis_mp_create_vc_complete co_miniport_create_vc_complete;
+    struct rcondis_mp_delete_vc_complete co_miniport_delete_vc_complete;
+    struct rcondis_mp_activate_vc_complete co_miniport_activate_vc_complete;
+    struct rcondis_mp_deactivate_vc_complete
+        co_miniport_deactivate_vc_complete;
+};
+
+/* Remote NDIS message format */
+struct rndis_msg_hdr {
+    uint32_t msg_type;
+    uint32_t msg_len;
+};
+
+#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 TRANSPORT_INFO_NOT_IP   0
+#define TRANSPORT_INFO_IPV4_TCP 0x01
+#define TRANSPORT_INFO_IPV4_UDP 0x02
+#define TRANSPORT_INFO_IPV6_TCP 0x10
+#define TRANSPORT_INFO_IPV6_UDP 0x20
+
+#endif