diff options
| author | Haiyang Zhang <haiyangz@microsoft.com> | 2014-02-19 18:49:45 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-02-19 19:52:45 -0500 |
| commit | a1eabb0178bcef8eee6286bc646b66e23f4f77ea (patch) | |
| tree | 68503c7c3732ce6b697fec768182ad5d2bdc6c57 /drivers/net/hyperv | |
| parent | 86c1a045640d3f34ca1ab2f3e8b102670d21f93a (diff) | |
hyperv: Add latest NetVSP versions to auto negotiation
It auto negotiates the highest NetVSP version supported by both guest and host.
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')
| -rw-r--r-- | drivers/net/hyperv/hyperv_net.h | 53 | ||||
| -rw-r--r-- | drivers/net/hyperv/netvsc.c | 25 | ||||
| -rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 2 |
3 files changed, 70 insertions, 10 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 01a16ea77a5a..39fc230f5c20 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
| @@ -139,6 +139,8 @@ int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac); | |||
| 139 | 139 | ||
| 140 | #define NVSP_PROTOCOL_VERSION_1 2 | 140 | #define NVSP_PROTOCOL_VERSION_1 2 |
| 141 | #define NVSP_PROTOCOL_VERSION_2 0x30002 | 141 | #define NVSP_PROTOCOL_VERSION_2 0x30002 |
| 142 | #define NVSP_PROTOCOL_VERSION_4 0x40000 | ||
| 143 | #define NVSP_PROTOCOL_VERSION_5 0x50000 | ||
| 142 | 144 | ||
| 143 | enum { | 145 | enum { |
| 144 | NVSP_MSG_TYPE_NONE = 0, | 146 | NVSP_MSG_TYPE_NONE = 0, |
| @@ -193,6 +195,23 @@ enum { | |||
| 193 | 195 | ||
| 194 | NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE, | 196 | NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE, |
| 195 | NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP, | 197 | NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP, |
| 198 | |||
| 199 | NVSP_MSG2_MAX = NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP, | ||
| 200 | |||
| 201 | /* Version 4 messages */ | ||
| 202 | NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION, | ||
| 203 | NVSP_MSG4_TYPE_SWITCH_DATA_PATH, | ||
| 204 | NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED, | ||
| 205 | |||
| 206 | NVSP_MSG4_MAX = NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED, | ||
| 207 | |||
| 208 | /* Version 5 messages */ | ||
| 209 | NVSP_MSG5_TYPE_OID_QUERY_EX, | ||
| 210 | NVSP_MSG5_TYPE_OID_QUERY_EX_COMP, | ||
| 211 | NVSP_MSG5_TYPE_SUBCHANNEL, | ||
| 212 | NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE, | ||
| 213 | |||
| 214 | NVSP_MSG5_MAX = NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE, | ||
| 196 | }; | 215 | }; |
| 197 | 216 | ||
| 198 | enum { | 217 | enum { |
| @@ -447,10 +466,44 @@ union nvsp_2_message_uber { | |||
| 447 | struct nvsp_2_free_rxbuf free_rxbuf; | 466 | struct nvsp_2_free_rxbuf free_rxbuf; |
| 448 | } __packed; | 467 | } __packed; |
| 449 | 468 | ||
| 469 | enum nvsp_subchannel_operation { | ||
| 470 | NVSP_SUBCHANNEL_NONE = 0, | ||
| 471 | NVSP_SUBCHANNEL_ALLOCATE, | ||
| 472 | NVSP_SUBCHANNEL_MAX | ||
| 473 | }; | ||
| 474 | |||
| 475 | struct nvsp_5_subchannel_request { | ||
| 476 | u32 op; | ||
| 477 | u32 num_subchannels; | ||
| 478 | } __packed; | ||
| 479 | |||
| 480 | struct nvsp_5_subchannel_complete { | ||
| 481 | u32 status; | ||
| 482 | u32 num_subchannels; /* Actual number of subchannels allocated */ | ||
| 483 | } __packed; | ||
| 484 | |||
| 485 | struct nvsp_5_send_indirect_table { | ||
| 486 | /* The number of entries in the send indirection table */ | ||
| 487 | u32 count; | ||
| 488 | |||
| 489 | /* The offset of the send indireciton table from top of this struct. | ||
| 490 | * The send indirection table tells which channel to put the send | ||
| 491 | * traffic on. Each entry is a channel number. | ||
| 492 | */ | ||
| 493 | u32 offset; | ||
| 494 | } __packed; | ||
| 495 | |||
| 496 | union nvsp_5_message_uber { | ||
| 497 | struct nvsp_5_subchannel_request subchn_req; | ||
| 498 | struct nvsp_5_subchannel_complete subchn_comp; | ||
| 499 | struct nvsp_5_send_indirect_table send_table; | ||
| 500 | } __packed; | ||
| 501 | |||
| 450 | union nvsp_all_messages { | 502 | union nvsp_all_messages { |
| 451 | union nvsp_message_init_uber init_msg; | 503 | union nvsp_message_init_uber init_msg; |
| 452 | union nvsp_1_message_uber v1_msg; | 504 | union nvsp_1_message_uber v1_msg; |
| 453 | union nvsp_2_message_uber v2_msg; | 505 | union nvsp_2_message_uber v2_msg; |
| 506 | union nvsp_5_message_uber v5_msg; | ||
| 454 | } __packed; | 507 | } __packed; |
| 455 | 508 | ||
| 456 | /* ALL Messages */ | 509 | /* ALL Messages */ |
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 9a0e9c6f1414..1a0280dcba7e 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
| @@ -290,7 +290,7 @@ static int negotiate_nvsp_ver(struct hv_device *device, | |||
| 290 | NVSP_STAT_SUCCESS) | 290 | NVSP_STAT_SUCCESS) |
| 291 | return -EINVAL; | 291 | return -EINVAL; |
| 292 | 292 | ||
| 293 | if (nvsp_ver != NVSP_PROTOCOL_VERSION_2) | 293 | if (nvsp_ver == NVSP_PROTOCOL_VERSION_1) |
| 294 | return 0; | 294 | return 0; |
| 295 | 295 | ||
| 296 | /* NVSPv2 only: Send NDIS config */ | 296 | /* NVSPv2 only: Send NDIS config */ |
| @@ -314,6 +314,9 @@ static int netvsc_connect_vsp(struct hv_device *device) | |||
| 314 | struct nvsp_message *init_packet; | 314 | struct nvsp_message *init_packet; |
| 315 | int ndis_version; | 315 | int ndis_version; |
| 316 | struct net_device *ndev; | 316 | struct net_device *ndev; |
| 317 | u32 ver_list[] = { NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2, | ||
| 318 | NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5 }; | ||
| 319 | int i, num_ver = 4; /* number of different NVSP versions */ | ||
| 317 | 320 | ||
| 318 | net_device = get_outbound_net_device(device); | 321 | net_device = get_outbound_net_device(device); |
| 319 | if (!net_device) | 322 | if (!net_device) |
| @@ -323,13 +326,14 @@ static int netvsc_connect_vsp(struct hv_device *device) | |||
| 323 | init_packet = &net_device->channel_init_pkt; | 326 | init_packet = &net_device->channel_init_pkt; |
| 324 | 327 | ||
| 325 | /* Negotiate the latest NVSP protocol supported */ | 328 | /* Negotiate the latest NVSP protocol supported */ |
| 326 | if (negotiate_nvsp_ver(device, net_device, init_packet, | 329 | for (i = num_ver - 1; i >= 0; i--) |
| 327 | NVSP_PROTOCOL_VERSION_2) == 0) { | 330 | if (negotiate_nvsp_ver(device, net_device, init_packet, |
| 328 | net_device->nvsp_version = NVSP_PROTOCOL_VERSION_2; | 331 | ver_list[i]) == 0) { |
| 329 | } else if (negotiate_nvsp_ver(device, net_device, init_packet, | 332 | net_device->nvsp_version = ver_list[i]; |
| 330 | NVSP_PROTOCOL_VERSION_1) == 0) { | 333 | break; |
| 331 | net_device->nvsp_version = NVSP_PROTOCOL_VERSION_1; | 334 | } |
| 332 | } else { | 335 | |
| 336 | if (i < 0) { | ||
| 333 | ret = -EPROTO; | 337 | ret = -EPROTO; |
| 334 | goto cleanup; | 338 | goto cleanup; |
| 335 | } | 339 | } |
| @@ -339,7 +343,10 @@ static int netvsc_connect_vsp(struct hv_device *device) | |||
| 339 | /* Send the ndis version */ | 343 | /* Send the ndis version */ |
| 340 | memset(init_packet, 0, sizeof(struct nvsp_message)); | 344 | memset(init_packet, 0, sizeof(struct nvsp_message)); |
| 341 | 345 | ||
| 342 | ndis_version = 0x00050001; | 346 | if (net_device->nvsp_version <= NVSP_PROTOCOL_VERSION_4) |
| 347 | ndis_version = 0x00050001; | ||
| 348 | else | ||
| 349 | ndis_version = 0x0006001e; | ||
| 343 | 350 | ||
| 344 | init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_NDIS_VER; | 351 | init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_NDIS_VER; |
| 345 | init_packet->msg.v1_msg. | 352 | init_packet->msg.v1_msg. |
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index bcd2df2f406a..9ef6be90a81c 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
| @@ -327,7 +327,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) | |||
| 327 | if (nvdev == NULL || nvdev->destroy) | 327 | if (nvdev == NULL || nvdev->destroy) |
| 328 | return -ENODEV; | 328 | return -ENODEV; |
| 329 | 329 | ||
| 330 | if (nvdev->nvsp_version == NVSP_PROTOCOL_VERSION_2) | 330 | if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2) |
| 331 | limit = NETVSC_MTU; | 331 | limit = NETVSC_MTU; |
| 332 | 332 | ||
| 333 | if (mtu < 68 || mtu > limit) | 333 | if (mtu < 68 || mtu > limit) |
