diff options
Diffstat (limited to 'drivers/net/hyperv/hyperv_net.h')
| -rw-r--r-- | drivers/net/hyperv/hyperv_net.h | 372 | 
1 files changed, 321 insertions, 51 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index e6fe0d80d61..6cc37c15e0b 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -12,8 +12,7 @@   * 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. + * this program; if not, see <http://www.gnu.org/licenses/>.   *   * Authors:   *   Haiyang Zhang <haiyangz@microsoft.com> @@ -29,52 +28,122 @@  #include <linux/hyperv.h>  #include <linux/rndis.h> -/* Fwd declaration */ -struct hv_netvsc_packet; +/* RSS related */ +#define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203  /* query only */ +#define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204  /* query and set */ -/* Represent the xfer page packet which contains 1 or more netvsc packet */ -struct xferpage_packet { -	struct list_head list_ent; -	u32 status; +#define NDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88 +#define NDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89 -	/* # of netvsc packets this xfer packet contains */ -	u32 count; +#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 +#define HASH_KEYLEN NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 +extern u8 netvsc_hash_key[]; + +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; +  /*   * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame   * within the RNDIS   */  struct hv_netvsc_packet {  	/* Bookkeeping stuff */ -	struct list_head list_ent;  	u32 status;  	struct hv_device *device;  	bool is_data_pkt;  	u16 vlan_tci; -	/* -	 * Valid only for receives when we break a xfer page packet -	 * into multiple netvsc packets -	 */ -	struct xferpage_packet *xfer_page_pkt; +	u16 q_idx; +	struct vmbus_channel *channel; -	union { -		struct { -			u64 recv_completion_tid; -			void *recv_completion_ctx; -			void (*recv_completion)(void *context); -		} recv; -		struct { -			u64 send_completion_tid; -			void *send_completion_ctx; -			void (*send_completion)(void *context); -		} send; -	} completion; +	u64 send_completion_tid; +	void *send_completion_ctx; +	void (*send_completion)(void *context); + +	u32 send_buf_index;  	/* This points to the memory after page_buf */ -	void *extension; +	struct rndis_message *rndis_msg;  	u32 total_data_buflen;  	/* Points to the send/receive buffer where the ethernet frame is */ @@ -118,7 +187,9 @@ int netvsc_send(struct hv_device *device,  void netvsc_linkstatus_callback(struct hv_device *device_obj,  				unsigned int status);  int netvsc_recv_callback(struct hv_device *device_obj, -			struct hv_netvsc_packet *packet); +			struct hv_netvsc_packet *packet, +			struct ndis_tcp_ip_checksum_info *csum_info); +void netvsc_channel_cb(void *context);  int rndis_filter_open(struct hv_device *dev);  int rndis_filter_close(struct hv_device *dev);  int rndis_filter_device_add(struct hv_device *dev, @@ -127,11 +198,6 @@ void rndis_filter_device_remove(struct hv_device *dev);  int rndis_filter_receive(struct hv_device *dev,  			struct hv_netvsc_packet *pkt); - - -int rndis_filter_send(struct hv_device *dev, -			struct hv_netvsc_packet *pkt); -  int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);  int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac); @@ -140,6 +206,8 @@ int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac);  #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, @@ -194,6 +262,23 @@ enum {  	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 { @@ -448,10 +533,44 @@ union nvsp_2_message_uber {  	struct nvsp_2_free_rxbuf free_rxbuf;  } __packed; +enum nvsp_subchannel_operation { +	NVSP_SUBCHANNEL_NONE = 0, +	NVSP_SUBCHANNEL_ALLOCATE, +	NVSP_SUBCHANNEL_MAX +}; + +struct nvsp_5_subchannel_request { +	u32 op; +	u32 num_subchannels; +} __packed; + +struct nvsp_5_subchannel_complete { +	u32 status; +	u32 num_subchannels; /* Actual number of subchannels allocated */ +} __packed; + +struct nvsp_5_send_indirect_table { +	/* The number of entries in the send indirection table */ +	u32 count; + +	/* The offset of the send indireciton 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. +	 */ +	u32 offset; +} __packed; + +union nvsp_5_message_uber { +	struct nvsp_5_subchannel_request subchn_req; +	struct nvsp_5_subchannel_complete subchn_comp; +	struct nvsp_5_send_indirect_table send_table; +} __packed; +  union nvsp_all_messages {  	union nvsp_message_init_uber init_msg;  	union nvsp_1_message_uber v1_msg;  	union nvsp_2_message_uber v2_msg; +	union nvsp_5_message_uber v5_msg;  } __packed;  /* ALL Messages */ @@ -463,15 +582,18 @@ struct nvsp_message {  #define NETVSC_MTU 65536 -#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024*2)	/* 2MB */ +#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)   /* 1MB */ +#define NETVSC_INVALID_INDEX			-1 -#define NETVSC_RECEIVE_BUFFER_ID		0xcafe -/* Preallocated receive packets */ -#define NETVSC_RECEIVE_PACKETLIST_COUNT		256 +#define NETVSC_RECEIVE_BUFFER_ID		0xcafe  #define NETVSC_PACKET_SIZE                      2048 +#define VRSS_SEND_TAB_SIZE 16 +  /* Per netvsc channel-specific */  struct netvsc_device {  	struct hv_device *dev; @@ -482,12 +604,6 @@ struct netvsc_device {  	wait_queue_head_t wait_drain;  	bool start_remove;  	bool destroy; -	/* -	 * List of free preallocated hv_netvsc_packet to represent receive -	 * packet -	 */ -	struct list_head recv_pkt_list; -	spinlock_t recv_pkt_list_lock;  	/* Receive buffer allocated by us but manages by NetVSP */  	void *recv_buf; @@ -496,6 +612,15 @@ struct netvsc_device {  	u32 recv_section_cnt;  	struct nvsp_1_receive_buffer_section *recv_section; +	/* Send buffer allocated by us */ +	void *send_buf; +	u32 send_buf_size; +	u32 send_buf_gpadl_handle; +	u32 send_section_cnt; +	u32 send_section_size; +	unsigned long *send_section_map; +	int map_words; +  	/* Used for NetVSP initialization protocol */  	struct completion channel_init_wait;  	struct nvsp_message channel_init_pkt; @@ -505,8 +630,20 @@ struct netvsc_device {  	struct net_device *ndev; +	struct vmbus_channel *chn_table[NR_CPUS]; +	u32 send_table[VRSS_SEND_TAB_SIZE]; +	u32 num_chn; +	atomic_t queue_sends[NR_CPUS]; +  	/* Holds rndis device info */  	void *extension; + +	int ring_size; + +	/* The primary channel callback buffer */ +	unsigned char cb_buffer[NETVSC_PACKET_SIZE]; +	/* The sub channel callback buffer */ +	unsigned char *sub_cb_buf;  };  /* NdisInitialize message */ @@ -654,6 +791,7 @@ enum ndis_per_pkt_info_type {  	IEEE_8021Q_INFO,  	ORIGINAL_PKTINFO,  	PACKET_CANCEL_ID, +	NBL_HASH_VALUE = PACKET_CANCEL_ID,  	ORIGINAL_NET_BUFLIST,  	CACHED_NET_BUFLIST,  	SHORT_PKT_PADINFO, @@ -672,9 +810,137 @@ struct ndis_pkt_8021q_info {  	};  }; +struct ndis_oject_header { +	u8 type; +	u8 revision; +	u16 size; +}; + +#define NDIS_OBJECT_TYPE_DEFAULT	0x80 +#define NDIS_OFFLOAD_PARAMETERS_REVISION_3 3 +#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 */ + +struct ndis_offload_params { +	struct ndis_oject_header header; +	u8 ip_v4_csum; +	u8 tcp_ip_v4_csum; +	u8 udp_ip_v4_csum; +	u8 tcp_ip_v6_csum; +	u8 udp_ip_v6_csum; +	u8 lso_v1; +	u8 ip_sec_v1; +	u8 lso_v2_ipv4; +	u8 lso_v2_ipv6; +	u8 tcp_connection_ip_v4; +	u8 tcp_connection_ip_v6; +	u32 flags; +	u8 ip_sec_v2; +	u8 ip_sec_v2_ip_v4; +	struct { +		u8 rsc_ip_v4; +		u8 rsc_ip_v6; +	}; +	struct { +		u8 encapsulated_packet_task_offload; +		u8 encapsulation_types; +	}; +}; + +struct ndis_tcp_ip_checksum_info { +	union { +		struct { +			u32 is_ipv4:1; +			u32 is_ipv6:1; +			u32 tcp_checksum:1; +			u32 udp_checksum:1; +			u32 ip_header_checksum:1; +			u32 reserved:11; +			u32 tcp_header_offset:10; +		} transmit; +		struct { +			u32 tcp_checksum_failed:1; +			u32 udp_checksum_failed:1; +			u32 ip_checksum_failed:1; +			u32 tcp_checksum_succeeded:1; +			u32 udp_checksum_succeeded:1; +			u32 ip_checksum_succeeded:1; +			u32 loopback:1; +			u32 tcp_checksum_value_invalid:1; +			u32 ip_checksum_value_invalid:1; +		} receive; +		u32  value; +	}; +}; + +struct ndis_tcp_lso_info { +	union { +		struct { +			u32 unused:30; +			u32 type:1; +			u32 reserved2:1; +		} transmit; +		struct { +			u32 mss:20; +			u32 tcp_header_offset:10; +			u32 type:1; +			u32 reserved2:1; +		} lso_v1_transmit; +		struct { +			u32 tcp_payload:30; +			u32 type:1; +			u32 reserved2:1; +		} lso_v1_transmit_complete; +		struct { +			u32 mss:20; +			u32 tcp_header_offset:10; +			u32 type:1; +			u32 ip_version:1; +		} lso_v2_transmit; +		struct { +			u32 reserved:30; +			u32 type:1; +			u32 reserved2:1; +		} lso_v2_transmit_complete; +		u32  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(u32)) +  /* Format of Information buffer passed in a SetRequest for the OID */  /* OID_GEN_RNDIS_CONFIG_PARAMETER. */  struct rndis_config_parameter_info { @@ -847,12 +1113,6 @@ struct rndis_message {  }; -struct rndis_filter_packet { -	void *completion_ctx; -	void (*completion)(void *context); -	struct rndis_message msg; -}; -  /* Handy macros */  /* get the size of an RNDIS message. Pass in the message type, */ @@ -906,6 +1166,16 @@ struct rndis_filter_packet {  #define NDIS_PACKET_TYPE_FUNCTIONAL	0x00000400  #define NDIS_PACKET_TYPE_MAC_FRAME	0x00000800 +#define INFO_IPV4       2 +#define INFO_IPV6       4 +#define INFO_TCP        2 +#define INFO_UDP        4 + +#define TRANSPORT_INFO_NOT_IP   0 +#define TRANSPORT_INFO_IPV4_TCP ((INFO_IPV4 << 16) | INFO_TCP) +#define TRANSPORT_INFO_IPV4_UDP ((INFO_IPV4 << 16) | INFO_UDP) +#define TRANSPORT_INFO_IPV6_TCP ((INFO_IPV6 << 16) | INFO_TCP) +#define TRANSPORT_INFO_IPV6_UDP ((INFO_IPV6 << 16) | INFO_UDP)  #endif /* _HYPERV_NET_H */  | 
