Drivers: net: hyperv: Address UDP checksum issues
[linux-2.6-microblaze.git] / drivers / net / hyperv / hyperv_net.h
index 7b594ce..d18f711 100644 (file)
@@ -30,6 +30,7 @@
 
 /* Fwd declaration */
 struct hv_netvsc_packet;
+struct ndis_tcp_ip_checksum_info;
 
 /* Represent the xfer page packet which contains 1 or more netvsc packet */
 struct xferpage_packet {
@@ -73,7 +74,7 @@ struct hv_netvsc_packet {
        } completion;
 
        /* 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 */
@@ -117,7 +118,8 @@ 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);
 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,
@@ -126,11 +128,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);
 
@@ -139,6 +136,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,
@@ -193,6 +192,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 {
@@ -447,10 +463,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,6 +513,7 @@ struct nvsp_message {
 #define NETVSC_MTU 65536
 
 #define NETVSC_RECEIVE_BUFFER_SIZE             (1024*1024*16)  /* 16MB */
+#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY      (1024*1024*15)  /* 15MB */
 
 #define NETVSC_RECEIVE_BUFFER_ID               0xcafe
 
@@ -506,6 +557,8 @@ struct netvsc_device {
 
        /* Holds rndis device info */
        void *extension;
+       /* The recive buffer for this device */
+       unsigned char cb_buffer[NETVSC_PACKET_SIZE];
 };
 
 /* NdisInitialize message */
@@ -671,9 +724,134 @@ 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))
+
 /* Format of Information buffer passed in a SetRequest for the OID */
 /* OID_GEN_RNDIS_CONFIG_PARAMETER. */
 struct rndis_config_parameter_info {
@@ -846,12 +1024,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, */
@@ -905,6 +1077,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 */