1 From 3c2a271d9681cc017947c5e027acc64707c30dee Mon Sep 17 00:00:00 2001
2 From: Haiyang Zhang <haiyangz@microsoft.com>
3 Date: Wed, 19 Feb 2014 15:49:45 -0800
4 Subject: [PATCH 04/25] hyperv: Add latest NetVSP versions to auto negotiation
6 It auto negotiates the highest NetVSP version supported by both guest and host.
8 Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
9 Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
10 Signed-off-by: David S. Miller <davem@davemloft.net>
12 drivers/net/hyperv/hyperv_net.h | 53 +++++++++++++++++++++++++++++++++++++++++
13 drivers/net/hyperv/netvsc.c | 25 ++++++++++++-------
14 drivers/net/hyperv/netvsc_drv.c | 2 +-
15 3 files changed, 70 insertions(+), 10 deletions(-)
17 diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
18 index 01a16ea77a5a..39fc230f5c20 100644
19 --- a/drivers/net/hyperv/hyperv_net.h
20 +++ b/drivers/net/hyperv/hyperv_net.h
21 @@ -139,6 +139,8 @@ int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac);
23 #define NVSP_PROTOCOL_VERSION_1 2
24 #define NVSP_PROTOCOL_VERSION_2 0x30002
25 +#define NVSP_PROTOCOL_VERSION_4 0x40000
26 +#define NVSP_PROTOCOL_VERSION_5 0x50000
29 NVSP_MSG_TYPE_NONE = 0,
30 @@ -193,6 +195,23 @@ enum {
32 NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE,
33 NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP,
35 + NVSP_MSG2_MAX = NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP,
37 + /* Version 4 messages */
38 + NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION,
39 + NVSP_MSG4_TYPE_SWITCH_DATA_PATH,
40 + NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED,
42 + NVSP_MSG4_MAX = NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED,
44 + /* Version 5 messages */
45 + NVSP_MSG5_TYPE_OID_QUERY_EX,
46 + NVSP_MSG5_TYPE_OID_QUERY_EX_COMP,
47 + NVSP_MSG5_TYPE_SUBCHANNEL,
48 + NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE,
50 + NVSP_MSG5_MAX = NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE,
54 @@ -447,10 +466,44 @@ union nvsp_2_message_uber {
55 struct nvsp_2_free_rxbuf free_rxbuf;
58 +enum nvsp_subchannel_operation {
59 + NVSP_SUBCHANNEL_NONE = 0,
60 + NVSP_SUBCHANNEL_ALLOCATE,
64 +struct nvsp_5_subchannel_request {
66 + u32 num_subchannels;
69 +struct nvsp_5_subchannel_complete {
71 + u32 num_subchannels; /* Actual number of subchannels allocated */
74 +struct nvsp_5_send_indirect_table {
75 + /* The number of entries in the send indirection table */
78 + /* The offset of the send indireciton table from top of this struct.
79 + * The send indirection table tells which channel to put the send
80 + * traffic on. Each entry is a channel number.
85 +union nvsp_5_message_uber {
86 + struct nvsp_5_subchannel_request subchn_req;
87 + struct nvsp_5_subchannel_complete subchn_comp;
88 + struct nvsp_5_send_indirect_table send_table;
91 union nvsp_all_messages {
92 union nvsp_message_init_uber init_msg;
93 union nvsp_1_message_uber v1_msg;
94 union nvsp_2_message_uber v2_msg;
95 + union nvsp_5_message_uber v5_msg;
99 diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
100 index 9a0e9c6f1414..1a0280dcba7e 100644
101 --- a/drivers/net/hyperv/netvsc.c
102 +++ b/drivers/net/hyperv/netvsc.c
103 @@ -290,7 +290,7 @@ static int negotiate_nvsp_ver(struct hv_device *device,
107 - if (nvsp_ver != NVSP_PROTOCOL_VERSION_2)
108 + if (nvsp_ver == NVSP_PROTOCOL_VERSION_1)
111 /* NVSPv2 only: Send NDIS config */
112 @@ -314,6 +314,9 @@ static int netvsc_connect_vsp(struct hv_device *device)
113 struct nvsp_message *init_packet;
115 struct net_device *ndev;
116 + u32 ver_list[] = { NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2,
117 + NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5 };
118 + int i, num_ver = 4; /* number of different NVSP versions */
120 net_device = get_outbound_net_device(device);
122 @@ -323,13 +326,14 @@ static int netvsc_connect_vsp(struct hv_device *device)
123 init_packet = &net_device->channel_init_pkt;
125 /* Negotiate the latest NVSP protocol supported */
126 - if (negotiate_nvsp_ver(device, net_device, init_packet,
127 - NVSP_PROTOCOL_VERSION_2) == 0) {
128 - net_device->nvsp_version = NVSP_PROTOCOL_VERSION_2;
129 - } else if (negotiate_nvsp_ver(device, net_device, init_packet,
130 - NVSP_PROTOCOL_VERSION_1) == 0) {
131 - net_device->nvsp_version = NVSP_PROTOCOL_VERSION_1;
133 + for (i = num_ver - 1; i >= 0; i--)
134 + if (negotiate_nvsp_ver(device, net_device, init_packet,
135 + ver_list[i]) == 0) {
136 + net_device->nvsp_version = ver_list[i];
144 @@ -339,7 +343,10 @@ static int netvsc_connect_vsp(struct hv_device *device)
145 /* Send the ndis version */
146 memset(init_packet, 0, sizeof(struct nvsp_message));
148 - ndis_version = 0x00050001;
149 + if (net_device->nvsp_version <= NVSP_PROTOCOL_VERSION_4)
150 + ndis_version = 0x00050001;
152 + ndis_version = 0x0006001e;
154 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_NDIS_VER;
155 init_packet->msg.v1_msg.
156 diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
157 index 28020f83ba6f..8e3a0b00099b 100644
158 --- a/drivers/net/hyperv/netvsc_drv.c
159 +++ b/drivers/net/hyperv/netvsc_drv.c
160 @@ -328,7 +328,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
161 if (nvdev == NULL || nvdev->destroy)
164 - if (nvdev->nvsp_version == NVSP_PROTOCOL_VERSION_2)
165 + if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
168 if (mtu < 68 || mtu > limit)