diff options
author | Haiyang Zhang <haiyangz@microsoft.com> | 2014-04-21 13:20:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-04-21 13:32:29 -0400 |
commit | 5b54dac856cb5bd6f33f4159012773e4a33704f7 (patch) | |
tree | b3aa8725ecf1605616632c305d76a3877969d685 /drivers/net/hyperv/hyperv_net.h | |
parent | 86fd14ad1e8c4b8f5e9a7a27b26bdade91dd4bd0 (diff) |
hyperv: Add support for virtual Receive Side Scaling (vRSS)
This feature allows multiple channels to be used by each virtual NIC.
It is available on Hyper-V host 2012 R2.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv/hyperv_net.h')
-rw-r--r-- | drivers/net/hyperv/hyperv_net.h | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index d18f711d0b0c..57eb3f906d64 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
@@ -28,6 +28,96 @@ | |||
28 | #include <linux/hyperv.h> | 28 | #include <linux/hyperv.h> |
29 | #include <linux/rndis.h> | 29 | #include <linux/rndis.h> |
30 | 30 | ||
31 | /* RSS related */ | ||
32 | #define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203 /* query only */ | ||
33 | #define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204 /* query and set */ | ||
34 | |||
35 | #define NDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88 | ||
36 | #define NDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89 | ||
37 | |||
38 | #define NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2 | ||
39 | #define NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2 | ||
40 | |||
41 | struct ndis_obj_header { | ||
42 | u8 type; | ||
43 | u8 rev; | ||
44 | u16 size; | ||
45 | } __packed; | ||
46 | |||
47 | /* ndis_recv_scale_cap/cap_flag */ | ||
48 | #define NDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x01000000 | ||
49 | #define NDIS_RSS_CAPS_CLASSIFICATION_AT_ISR 0x02000000 | ||
50 | #define NDIS_RSS_CAPS_CLASSIFICATION_AT_DPC 0x04000000 | ||
51 | #define NDIS_RSS_CAPS_USING_MSI_X 0x08000000 | ||
52 | #define NDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS 0x10000000 | ||
53 | #define NDIS_RSS_CAPS_SUPPORTS_MSI_X 0x20000000 | ||
54 | #define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4 0x00000100 | ||
55 | #define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6 0x00000200 | ||
56 | #define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX 0x00000400 | ||
57 | |||
58 | struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */ | ||
59 | struct ndis_obj_header hdr; | ||
60 | u32 cap_flag; | ||
61 | u32 num_int_msg; | ||
62 | u32 num_recv_que; | ||
63 | u16 num_indirect_tabent; | ||
64 | } __packed; | ||
65 | |||
66 | |||
67 | /* ndis_recv_scale_param flags */ | ||
68 | #define NDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED 0x0001 | ||
69 | #define NDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED 0x0002 | ||
70 | #define NDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED 0x0004 | ||
71 | #define NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED 0x0008 | ||
72 | #define NDIS_RSS_PARAM_FLAG_DISABLE_RSS 0x0010 | ||
73 | |||
74 | /* Hash info bits */ | ||
75 | #define NDIS_HASH_FUNC_TOEPLITZ 0x00000001 | ||
76 | #define NDIS_HASH_IPV4 0x00000100 | ||
77 | #define NDIS_HASH_TCP_IPV4 0x00000200 | ||
78 | #define NDIS_HASH_IPV6 0x00000400 | ||
79 | #define NDIS_HASH_IPV6_EX 0x00000800 | ||
80 | #define NDIS_HASH_TCP_IPV6 0x00001000 | ||
81 | #define NDIS_HASH_TCP_IPV6_EX 0x00002000 | ||
82 | |||
83 | #define NDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4) | ||
84 | #define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 40 | ||
85 | |||
86 | #define ITAB_NUM 128 | ||
87 | #define HASH_KEYLEN NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 | ||
88 | extern u8 netvsc_hash_key[]; | ||
89 | |||
90 | struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */ | ||
91 | struct ndis_obj_header hdr; | ||
92 | |||
93 | /* Qualifies the rest of the information */ | ||
94 | u16 flag; | ||
95 | |||
96 | /* The base CPU number to do receive processing. not used */ | ||
97 | u16 base_cpu_number; | ||
98 | |||
99 | /* This describes the hash function and type being enabled */ | ||
100 | u32 hashinfo; | ||
101 | |||
102 | /* The size of indirection table array */ | ||
103 | u16 indirect_tabsize; | ||
104 | |||
105 | /* The offset of the indirection table from the beginning of this | ||
106 | * structure | ||
107 | */ | ||
108 | u32 indirect_taboffset; | ||
109 | |||
110 | /* The size of the hash secret key */ | ||
111 | u16 hashkey_size; | ||
112 | |||
113 | /* The offset of the secret key from the beginning of this structure */ | ||
114 | u32 kashkey_offset; | ||
115 | |||
116 | u32 processor_masks_offset; | ||
117 | u32 num_processor_masks; | ||
118 | u32 processor_masks_entry_size; | ||
119 | }; | ||
120 | |||
31 | /* Fwd declaration */ | 121 | /* Fwd declaration */ |
32 | struct hv_netvsc_packet; | 122 | struct hv_netvsc_packet; |
33 | struct ndis_tcp_ip_checksum_info; | 123 | struct ndis_tcp_ip_checksum_info; |
@@ -39,6 +129,8 @@ struct xferpage_packet { | |||
39 | 129 | ||
40 | /* # of netvsc packets this xfer packet contains */ | 130 | /* # of netvsc packets this xfer packet contains */ |
41 | u32 count; | 131 | u32 count; |
132 | |||
133 | struct vmbus_channel *channel; | ||
42 | }; | 134 | }; |
43 | 135 | ||
44 | /* | 136 | /* |
@@ -54,6 +146,9 @@ struct hv_netvsc_packet { | |||
54 | bool is_data_pkt; | 146 | bool is_data_pkt; |
55 | u16 vlan_tci; | 147 | u16 vlan_tci; |
56 | 148 | ||
149 | u16 q_idx; | ||
150 | struct vmbus_channel *channel; | ||
151 | |||
57 | /* | 152 | /* |
58 | * Valid only for receives when we break a xfer page packet | 153 | * Valid only for receives when we break a xfer page packet |
59 | * into multiple netvsc packets | 154 | * into multiple netvsc packets |
@@ -120,6 +215,7 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, | |||
120 | int netvsc_recv_callback(struct hv_device *device_obj, | 215 | int netvsc_recv_callback(struct hv_device *device_obj, |
121 | struct hv_netvsc_packet *packet, | 216 | struct hv_netvsc_packet *packet, |
122 | struct ndis_tcp_ip_checksum_info *csum_info); | 217 | struct ndis_tcp_ip_checksum_info *csum_info); |
218 | void netvsc_channel_cb(void *context); | ||
123 | int rndis_filter_open(struct hv_device *dev); | 219 | int rndis_filter_open(struct hv_device *dev); |
124 | int rndis_filter_close(struct hv_device *dev); | 220 | int rndis_filter_close(struct hv_device *dev); |
125 | int rndis_filter_device_add(struct hv_device *dev, | 221 | int rndis_filter_device_add(struct hv_device *dev, |
@@ -522,6 +618,8 @@ struct nvsp_message { | |||
522 | 618 | ||
523 | #define NETVSC_PACKET_SIZE 2048 | 619 | #define NETVSC_PACKET_SIZE 2048 |
524 | 620 | ||
621 | #define VRSS_SEND_TAB_SIZE 16 | ||
622 | |||
525 | /* Per netvsc channel-specific */ | 623 | /* Per netvsc channel-specific */ |
526 | struct netvsc_device { | 624 | struct netvsc_device { |
527 | struct hv_device *dev; | 625 | struct hv_device *dev; |
@@ -555,10 +653,20 @@ struct netvsc_device { | |||
555 | 653 | ||
556 | struct net_device *ndev; | 654 | struct net_device *ndev; |
557 | 655 | ||
656 | struct vmbus_channel *chn_table[NR_CPUS]; | ||
657 | u32 send_table[VRSS_SEND_TAB_SIZE]; | ||
658 | u32 num_chn; | ||
659 | atomic_t queue_sends[NR_CPUS]; | ||
660 | |||
558 | /* Holds rndis device info */ | 661 | /* Holds rndis device info */ |
559 | void *extension; | 662 | void *extension; |
560 | /* The recive buffer for this device */ | 663 | |
664 | int ring_size; | ||
665 | |||
666 | /* The primary channel callback buffer */ | ||
561 | unsigned char cb_buffer[NETVSC_PACKET_SIZE]; | 667 | unsigned char cb_buffer[NETVSC_PACKET_SIZE]; |
668 | /* The sub channel callback buffer */ | ||
669 | unsigned char *sub_cb_buf; | ||
562 | }; | 670 | }; |
563 | 671 | ||
564 | /* NdisInitialize message */ | 672 | /* NdisInitialize message */ |