Skip to content

Commit

Permalink
hv_netvsc: Add handler for physical link speed change
Browse files Browse the repository at this point in the history
On Hyper-V host 2016 and later, VMs gets an event message of the physical
link speed when vSwitch is changed. This patch handles this message, so
the updated link speed can be reported by ethtool.

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>
  • Loading branch information
Haiyang Zhang authored and David S. Miller committed Aug 8, 2016
1 parent b37879e commit 7f5d5af
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
1 change: 1 addition & 0 deletions drivers/net/hyperv/hyperv_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ struct nvsp_2_vsc_capability {
u64 sriov:1;
u64 ieee8021q:1;
u64 correlation_id:1;
u64 teaming:1;
};
};
} __packed;
Expand Down
6 changes: 5 additions & 1 deletion drivers/net/hyperv/netvsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,13 @@ static int negotiate_nvsp_ver(struct hv_device *device,
init_packet->msg.v2_msg.send_ndis_config.mtu = ndev->mtu + ETH_HLEN;
init_packet->msg.v2_msg.send_ndis_config.capability.ieee8021q = 1;

if (nvsp_ver >= NVSP_PROTOCOL_VERSION_5)
if (nvsp_ver >= NVSP_PROTOCOL_VERSION_5) {
init_packet->msg.v2_msg.send_ndis_config.capability.sriov = 1;

/* Teaming bit is needed to receive link speed updates */
init_packet->msg.v2_msg.send_ndis_config.capability.teaming = 1;
}

ret = vmbus_sendpacket(device->channel, init_packet,
sizeof(struct nvsp_message),
(unsigned long)init_packet,
Expand Down
25 changes: 19 additions & 6 deletions drivers/net/hyperv/netvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,19 +579,32 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
struct netvsc_reconfig *event;
unsigned long flags;

/* Handle link change statuses only */
net = hv_get_drvdata(device_obj);

if (!net)
return;

ndev_ctx = netdev_priv(net);

/* Update the physical link speed when changing to another vSwitch */
if (indicate->status == RNDIS_STATUS_LINK_SPEED_CHANGE) {
u32 speed;

speed = *(u32 *)((void *)indicate + indicate->
status_buf_offset) / 10000;
ndev_ctx->speed = speed;
return;
}

/* Handle these link change statuses below */
if (indicate->status != RNDIS_STATUS_NETWORK_CHANGE &&
indicate->status != RNDIS_STATUS_MEDIA_CONNECT &&
indicate->status != RNDIS_STATUS_MEDIA_DISCONNECT)
return;

net = hv_get_drvdata(device_obj);

if (!net || net->reg_state != NETREG_REGISTERED)
if (net->reg_state != NETREG_REGISTERED)
return;

ndev_ctx = netdev_priv(net);

event = kzalloc(sizeof(*event), GFP_ATOMIC);
if (!event)
return;
Expand Down

0 comments on commit 7f5d5af

Please sign in to comment.