]>
Commit | Line | Data |
---|---|---|
a7b0967d MT |
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 | |
5 | ||
6 | It auto negotiates the highest NetVSP version supported by both guest and host. | |
7 | ||
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> | |
11 | --- | |
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(-) | |
16 | ||
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); | |
22 | ||
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 | |
27 | ||
28 | enum { | |
29 | NVSP_MSG_TYPE_NONE = 0, | |
30 | @@ -193,6 +195,23 @@ enum { | |
31 | ||
32 | NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE, | |
33 | NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP, | |
34 | + | |
35 | + NVSP_MSG2_MAX = NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP, | |
36 | + | |
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, | |
41 | + | |
42 | + NVSP_MSG4_MAX = NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED, | |
43 | + | |
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, | |
49 | + | |
50 | + NVSP_MSG5_MAX = NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE, | |
51 | }; | |
52 | ||
53 | enum { | |
54 | @@ -447,10 +466,44 @@ union nvsp_2_message_uber { | |
55 | struct nvsp_2_free_rxbuf free_rxbuf; | |
56 | } __packed; | |
57 | ||
58 | +enum nvsp_subchannel_operation { | |
59 | + NVSP_SUBCHANNEL_NONE = 0, | |
60 | + NVSP_SUBCHANNEL_ALLOCATE, | |
61 | + NVSP_SUBCHANNEL_MAX | |
62 | +}; | |
63 | + | |
64 | +struct nvsp_5_subchannel_request { | |
65 | + u32 op; | |
66 | + u32 num_subchannels; | |
67 | +} __packed; | |
68 | + | |
69 | +struct nvsp_5_subchannel_complete { | |
70 | + u32 status; | |
71 | + u32 num_subchannels; /* Actual number of subchannels allocated */ | |
72 | +} __packed; | |
73 | + | |
74 | +struct nvsp_5_send_indirect_table { | |
75 | + /* The number of entries in the send indirection table */ | |
76 | + u32 count; | |
77 | + | |
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. | |
81 | + */ | |
82 | + u32 offset; | |
83 | +} __packed; | |
84 | + | |
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; | |
89 | +} __packed; | |
90 | + | |
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; | |
96 | } __packed; | |
97 | ||
98 | /* ALL Messages */ | |
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, | |
104 | NVSP_STAT_SUCCESS) | |
105 | return -EINVAL; | |
106 | ||
107 | - if (nvsp_ver != NVSP_PROTOCOL_VERSION_2) | |
108 | + if (nvsp_ver == NVSP_PROTOCOL_VERSION_1) | |
109 | return 0; | |
110 | ||
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; | |
114 | int ndis_version; | |
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 */ | |
119 | ||
120 | net_device = get_outbound_net_device(device); | |
121 | if (!net_device) | |
122 | @@ -323,13 +326,14 @@ static int netvsc_connect_vsp(struct hv_device *device) | |
123 | init_packet = &net_device->channel_init_pkt; | |
124 | ||
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; | |
132 | - } else { | |
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]; | |
137 | + break; | |
138 | + } | |
139 | + | |
140 | + if (i < 0) { | |
141 | ret = -EPROTO; | |
142 | goto cleanup; | |
143 | } | |
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)); | |
147 | ||
148 | - ndis_version = 0x00050001; | |
149 | + if (net_device->nvsp_version <= NVSP_PROTOCOL_VERSION_4) | |
150 | + ndis_version = 0x00050001; | |
151 | + else | |
152 | + ndis_version = 0x0006001e; | |
153 | ||
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) | |
162 | return -ENODEV; | |
163 | ||
164 | - if (nvdev->nvsp_version == NVSP_PROTOCOL_VERSION_2) | |
165 | + if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2) | |
166 | limit = NETVSC_MTU; | |
167 | ||
168 | if (mtu < 68 || mtu > limit) | |
169 | -- | |
170 | 2.4.3 | |
171 |