/* * * Copyright (c) 2011, Microsoft Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, see <http://www.gnu.org/licenses/>. * * Authors: * Haiyang Zhang <haiyangz@microsoft.com> * Hank Janssen <hjanssen@microsoft.com> * K. Y. Srinivasan <kys@microsoft.com> * */ #ifndef _HYPERV_NET_H#define _HYPERV_NET_H #include <linux/list.h>#include <linux/hyperv.h>#include <linux/rndis.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 { u8 type; u8 rev; u16 size;} __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; u32 cap_flag; u32 num_int_msg; u32 num_recv_que; u16 num_indirect_tabent;} __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 */ u16 flag; /* The base CPU number to do receive processing. not used */ u16 base_cpu_number; /* This describes the hash function and type being enabled */ u32 hashinfo; /* The size of indirection table array */ u16 indirect_tabsize; /* The offset of the indirection table from the beginning of this * structure */ u32 indirect_taboffset; /* The size of the hash secret key */ u16 hashkey_size; /* The offset of the secret key from the beginning of this structure */ u32 kashkey_offset; u32 processor_masks_offset; u32 num_processor_masks; u32 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 */ u8 cp_partial; /* partial copy into send buffer */ u8 rmsg_size; /* RNDIS header and PPI size */ u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */ u8 page_buf_cnt; u16 q_idx; u16 total_packets; u32 total_bytes; u32 send_buf_index; u32 total_data_buflen;}; struct netvsc_device_info { unsigned char mac_adr[ETH_ALEN]; int ring_size; u32 max_num_vrss_chns; u32 num_chn;}; enum rndis_device_state { RNDIS_DEV_UNINITIALIZED = 0, RNDIS_DEV_INITIALIZING, RNDIS_DEV_INITIALIZED, RNDIS_DEV_DATAINITIALIZED,}; #define NETVSC_HASH_KEYLEN 40 struct rndis_device { struct net_device *ndev; enum rndis_device_state state; atomic_t new_req_id; spinlock_t request_lock; struct list_head req_list; struct work_struct mcast_work; bool link_state; /* 0 - link up, 1 - link down */ u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN]; u16 ind_table[ITAB_NUM];}; /* Interface */struct rndis_message;struct netvsc_device;int netvsc_device_add(struct hv_device *device, const struct netvsc_device_info *info);void netvsc_device_remove(struct hv_device *device);int netvsc_send(struct hv_device *device, struct hv_netvsc_packet *packet, struct rndis_message *rndis_msg, struct hv_page_buffer **page_buffer, struct sk_buff *skb);void netvsc_linkstatus_callback(struct hv_device *device_obj, struct rndis_message *resp);int netvsc_recv_callback(struct net_device *net, struct vmbus_channel *channel, void *data, u32 len, const struct ndis_tcp_ip_checksum_info *csum_info, const struct ndis_pkt_8021q_info *vlan);void netvsc_channel_cb(void *context);int netvsc_poll(struct napi_struct *napi, int budget);int rndis_filter_open(struct netvsc_device *nvdev);int rndis_filter_close(struct netvsc_device *nvdev);int rndis_filter_device_add(struct hv_device *dev, struct netvsc_device_info *info);void rndis_filter_update(struct netvsc_device *nvdev);void rndis_filter_device_remove(struct hv_device *dev, struct netvsc_device *nvdev);int rndis_filter_set_rss_param(struct rndis_device *rdev, const u8 *key, int num_queue);int rndis_filter_receive(struct net_device *ndev, struct netvsc_device *net_dev, struct hv_device *dev, struct vmbus_channel *channel, void *data, u32 buflen); int rndis_filter_set_device_mac(struct net_device *ndev, char *mac); void netvsc_switch_datapath(struct net_device *nv_dev, bool vf); #define NVSP_INVALID_PROTOCOL_VERSION ((u32)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_message_header { u32 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_message_init { u32 min_protocol_ver; u32 max_protocol_ver;} __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_message_init_complete { u32 negotiated_protocol_ver; u32 max_mdl_chain_len; u32 status;} __packed; union nvsp_message_init_uber { struct nvsp_message_init init; struct nvsp_message_init_complete init_complete;} __packed; /* 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 nvsp_1_message_send_ndis_version { u32 ndis_major_ver; u32 ndis_minor_ver;} __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 nvsp_1_message_send_receive_buffer { u32 gpadl_handle; u16 id;} __packed; struct nvsp_1_receive_buffer_section { u32 offset; u32 sub_alloc_size; u32 num_sub_allocs; u32 end_offset;} __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 nvsp_1_message_send_receive_buffer_complete { u32 status; u32 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 nvsp_1_receive_buffer_section sections[1];} __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 nvsp_1_message_revoke_receive_buffer { u16 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 nvsp_1_message_send_send_buffer { u32 gpadl_handle; u16 id;} __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 nvsp_1_message_send_send_buffer_complete { u32 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. */ u32 section_size;} __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 nvsp_1_message_revoke_send_buffer { u16 id;}; /* * This message is used by both the VSP and the VSC to send a RNDIS message to * the opposite channel endpoint. */struct nvsp_1_message_send_rndis_packet { /* * 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. */ u32 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. */ u32 send_buf_section_index; u32 send_buf_section_size;} __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 nvsp_1_message_send_rndis_packet_complete { u32 status;}; union nvsp_1_message_uber { struct nvsp_1_message_send_ndis_version send_ndis_ver; struct nvsp_1_message_send_receive_buffer send_recv_buf; struct nvsp_1_message_send_receive_buffer_complete send_recv_buf_complete; struct nvsp_1_message_revoke_receive_buffer revoke_recv_buf; struct nvsp_1_message_send_send_buffer send_send_buf; struct nvsp_1_message_send_send_buffer_complete send_send_buf_complete; struct nvsp_1_message_revoke_send_buffer revoke_send_buf; struct nvsp_1_message_send_rndis_packet send_rndis_pkt; struct nvsp_1_message_send_rndis_packet_complete send_rndis_pkt_complete;} __packed; /* * Network VSP protocol version 2 messages: */struct nvsp_2_vsc_capability { union { u64 data;Lines 1–500 of 1458. Load more
/* * * Copyright (c) 2011, Microsoft Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, see <http://www.gnu.org/licenses/>. * * Authors: * Haiyang Zhang <haiyangz@microsoft.com> * Hank Janssen <hjanssen@microsoft.com> * K. Y. Srinivasan <kys@microsoft.com> * */ #ifndef _HYPERV_NET_H #define _HYPERV_NET_H #include <linux/list.h> #include <linux/hyperv.h> #include <linux/rndis.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 { u8 type; u8 rev; u16 size; } __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; u32 cap_flag; u32 num_int_msg; u32 num_recv_que; u16 num_indirect_tabent; } __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 */ u16 flag; /* The base CPU number to do receive processing. not used */ u16 base_cpu_number; /* This describes the hash function and type being enabled */ u32 hashinfo; /* The size of indirection table array */ u16 indirect_tabsize; /* The offset of the indirection table from the beginning of this * structure */ u32 indirect_taboffset; /* The size of the hash secret key */ u16 hashkey_size; /* The offset of the secret key from the beginning of this structure */ u32 kashkey_offset; u32 processor_masks_offset; u32 num_processor_masks; u32 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 */ u8 cp_partial; /* partial copy into send buffer */ u8 rmsg_size; /* RNDIS header and PPI size */ u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */ u8 page_buf_cnt; u16 q_idx; u16 total_packets; u32 total_bytes; u32 send_buf_index; u32 total_data_buflen; }; struct netvsc_device_info { unsigned char mac_adr[ETH_ALEN]; int ring_size; u32 max_num_vrss_chns; u32 num_chn; }; enum rndis_device_state { RNDIS_DEV_UNINITIALIZED = 0, RNDIS_DEV_INITIALIZING, RNDIS_DEV_INITIALIZED, RNDIS_DEV_DATAINITIALIZED, }; #define NETVSC_HASH_KEYLEN 40 struct rndis_device { struct net_device *ndev; enum rndis_device_state state; atomic_t new_req_id; spinlock_t request_lock; struct list_head req_list; struct work_struct mcast_work; bool link_state; /* 0 - link up, 1 - link down */ u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN]; u16 ind_table[ITAB_NUM]; }; /* Interface */ struct rndis_message; struct netvsc_device; int netvsc_device_add(struct hv_device *device, const struct netvsc_device_info *info); void netvsc_device_remove(struct hv_device *device); int netvsc_send(struct hv_device *device, struct hv_netvsc_packet *packet, struct rndis_message *rndis_msg, struct hv_page_buffer **page_buffer, struct sk_buff *skb); void netvsc_linkstatus_callback(struct hv_device *device_obj, struct rndis_message *resp); int netvsc_recv_callback(struct net_device *net, struct vmbus_channel *channel, void *data, u32 len, const struct ndis_tcp_ip_checksum_info *csum_info, const struct ndis_pkt_8021q_info *vlan); void netvsc_channel_cb(void *context); int netvsc_poll(struct napi_struct *napi, int budget); int rndis_filter_open(struct netvsc_device *nvdev); int rndis_filter_close(struct netvsc_device *nvdev); int rndis_filter_device_add(struct hv_device *dev, struct netvsc_device_info *info); void rndis_filter_update(struct netvsc_device *nvdev); void rndis_filter_device_remove(struct hv_device *dev, struct netvsc_device *nvdev); int rndis_filter_set_rss_param(struct rndis_device *rdev, const u8 *key, int num_queue); int rndis_filter_receive(struct net_device *ndev, struct netvsc_device *net_dev, struct hv_device *dev, struct vmbus_channel *channel, void *data, u32 buflen); int rndis_filter_set_device_mac(struct net_device *ndev, char *mac); void netvsc_switch_datapath(struct net_device *nv_dev, bool vf); #define NVSP_INVALID_PROTOCOL_VERSION ((u32)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_message_header { u32 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_message_init { u32 min_protocol_ver; u32 max_protocol_ver; } __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_message_init_complete { u32 negotiated_protocol_ver; u32 max_mdl_chain_len; u32 status; } __packed; union nvsp_message_init_uber { struct nvsp_message_init init; struct nvsp_message_init_complete init_complete; } __packed; /* 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 nvsp_1_message_send_ndis_version { u32 ndis_major_ver; u32 ndis_minor_ver; } __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 nvsp_1_message_send_receive_buffer { u32 gpadl_handle; u16 id; } __packed; struct nvsp_1_receive_buffer_section { u32 offset; u32 sub_alloc_size; u32 num_sub_allocs; u32 end_offset; } __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 nvsp_1_message_send_receive_buffer_complete { u32 status; u32 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 nvsp_1_receive_buffer_section sections[1]; } __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 nvsp_1_message_revoke_receive_buffer { u16 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 nvsp_1_message_send_send_buffer { u32 gpadl_handle; u16 id; } __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 nvsp_1_message_send_send_buffer_complete { u32 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. */ u32 section_size; } __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 nvsp_1_message_revoke_send_buffer { u16 id; }; /* * This message is used by both the VSP and the VSC to send a RNDIS message to * the opposite channel endpoint. */ struct nvsp_1_message_send_rndis_packet { /* * 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. */ u32 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. */ u32 send_buf_section_index; u32 send_buf_section_size; } __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 nvsp_1_message_send_rndis_packet_complete { u32 status; }; union nvsp_1_message_uber { struct nvsp_1_message_send_ndis_version send_ndis_ver; struct nvsp_1_message_send_receive_buffer send_recv_buf; struct nvsp_1_message_send_receive_buffer_complete send_recv_buf_complete; struct nvsp_1_message_revoke_receive_buffer revoke_recv_buf; struct nvsp_1_message_send_send_buffer send_send_buf; struct nvsp_1_message_send_send_buffer_complete send_send_buf_complete; struct nvsp_1_message_revoke_send_buffer revoke_send_buf; struct nvsp_1_message_send_rndis_packet send_rndis_pkt; struct nvsp_1_message_send_rndis_packet_complete send_rndis_pkt_complete; } __packed; /* * Network VSP protocol version 2 messages: */ struct nvsp_2_vsc_capability { union { u64 data;