| /* |
| * |
| * Copyright (c) 2009, 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, write to the Free Software Foundation, Inc., 59 Temple |
| * Place - Suite 330, Boston, MA 02111-1307 USA. |
| * |
| * Authors: |
| * Haiyang Zhang <haiyangz@microsoft.com> |
| * Hank Janssen <hjanssen@microsoft.com> |
| * |
| */ |
| |
| |
| #ifndef _NETVSC_H_ |
| #define _NETVSC_H_ |
| |
| #include <linux/list.h> |
| #include "vmbus_packet_format.h" |
| #include "vmbus_channel_interface.h" |
| #include "netvsc_api.h" |
| |
| |
| #define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF) |
| |
| #define NVSP_PROTOCOL_VERSION_1 2 |
| #define NVSP_MIN_PROTOCOL_VERSION NVSP_PROTOCOL_VERSION_1 |
| #define NVSP_MAX_PROTOCOL_VERSION NVSP_PROTOCOL_VERSION_1 |
| |
| 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, |
| |
| /* |
| * This should be set to the number of messages for the version with |
| * the maximum number of messages. |
| */ |
| NVSP_NUM_MSG_PER_VERSION = 9, |
| }; |
| |
| 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_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; |
| } __attribute__((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; |
| } __attribute__((packed)); |
| |
| union nvsp_message_init_uber { |
| struct nvsp_message_init init; |
| struct nvsp_message_init_complete init_complete; |
| } __attribute__((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; |
| } __attribute__((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; |
| } __attribute__((packed)); |
| |
| struct nvsp_1_receive_buffer_section { |
| u32 offset; |
| u32 sub_alloc_size; |
| u32 num_sub_allocs; |
| u32 end_offset; |
| } __attribute__((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]; |
| } __attribute__((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; |
| } __attribute__((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; |
| } __attribute__((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 RNIDS. 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; |
| } __attribute__((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; |
| } __attribute__((packed)); |
| |
| union nvsp_all_messages { |
| union nvsp_message_init_uber init_msg; |
| union nvsp_1_message_uber v1_msg; |
| } __attribute__((packed)); |
| |
| /* ALL Messages */ |
| struct nvsp_message { |
| struct nvsp_message_header hdr; |
| union nvsp_all_messages msg; |
| } __attribute__((packed)); |
| |
| |
| |
| |
| /* #define NVSC_MIN_PROTOCOL_VERSION 1 */ |
| /* #define NVSC_MAX_PROTOCOL_VERSION 1 */ |
| |
| #define NETVSC_SEND_BUFFER_SIZE (64*1024) /* 64K */ |
| #define NETVSC_SEND_BUFFER_ID 0xface |
| |
| |
| #define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024) /* 1MB */ |
| |
| #define NETVSC_RECEIVE_BUFFER_ID 0xcafe |
| |
| #define NETVSC_RECEIVE_SG_COUNT 1 |
| |
| /* Preallocated receive packets */ |
| #define NETVSC_RECEIVE_PACKETLIST_COUNT 256 |
| |
| #define NETVSC_PACKET_SIZE 2048 |
| |
| /* Per netvsc channel-specific */ |
| struct netvsc_device { |
| struct hv_device *dev; |
| |
| atomic_t refcnt; |
| atomic_t num_outstanding_sends; |
| /* |
| * List of free preallocated hv_netvsc_packet to represent receive |
| * packet |
| */ |
| struct list_head recv_pkt_list; |
| spinlock_t recv_pkt_list_lock; |
| |
| /* Send buffer allocated by us but manages by NetVSP */ |
| void *send_buf; |
| u32 send_buf_size; |
| u32 send_buf_gpadl_handle; |
| u32 send_section_size; |
| |
| /* Receive buffer allocated by us but manages by NetVSP */ |
| void *recv_buf; |
| u32 recv_buf_size; |
| u32 recv_buf_gpadl_handle; |
| u32 recv_section_cnt; |
| struct nvsp_1_receive_buffer_section *recv_section; |
| |
| /* Used for NetVSP initialization protocol */ |
| struct osd_waitevent *channel_init_event; |
| struct nvsp_message channel_init_pkt; |
| |
| struct nvsp_message revoke_packet; |
| /* unsigned char HwMacAddr[HW_MACADDR_LEN]; */ |
| |
| /* Holds rndis device info */ |
| void *extension; |
| }; |
| |
| #endif /* _NETVSC_H_ */ |