diff options
Diffstat (limited to 'drivers/net/hyperv/netvsc.c')
-rw-r--r-- | drivers/net/hyperv/netvsc.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 31c3d77b4733..922054c1d544 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -542,6 +542,9 @@ static int negotiate_nvsp_ver(struct hv_device *device, init_packet->msg.v2_msg.send_ndis_config.capability.teaming = 1; } + if (nvsp_ver >= NVSP_PROTOCOL_VERSION_61) + init_packet->msg.v2_msg.send_ndis_config.capability.rsc = 1; + trace_nvsp_send(ndev, init_packet); ret = vmbus_sendpacket(device->channel, init_packet, @@ -1111,11 +1114,12 @@ static void enq_receive_complete(struct net_device *ndev, static int netvsc_receive(struct net_device *ndev, struct netvsc_device *net_device, - struct vmbus_channel *channel, + struct netvsc_channel *nvchan, const struct vmpacket_descriptor *desc, const struct nvsp_message *nvsp) { struct net_device_context *net_device_ctx = netdev_priv(ndev); + struct vmbus_channel *channel = nvchan->channel; const struct vmtransfer_page_packet_header *vmxferpage_packet = container_of(desc, const struct vmtransfer_page_packet_header, d); u16 q_idx = channel->offermsg.offer.sub_channel_index; @@ -1150,6 +1154,7 @@ static int netvsc_receive(struct net_device *ndev, int ret; if (unlikely(offset + buflen > net_device->recv_buf_size)) { + nvchan->rsc.cnt = 0; status = NVSP_STAT_FAIL; netif_err(net_device_ctx, rx_err, ndev, "Packet offset:%u + len:%u too big\n", @@ -1160,11 +1165,13 @@ static int netvsc_receive(struct net_device *ndev, data = recv_buf + offset; + nvchan->rsc.is_last = (i == count - 1); + trace_rndis_recv(ndev, q_idx, data); /* Pass it to the upper layer */ ret = rndis_filter_receive(ndev, net_device, - channel, data, buflen); + nvchan, data, buflen); if (unlikely(ret != NVSP_STAT_SUCCESS)) status = NVSP_STAT_FAIL; @@ -1203,6 +1210,9 @@ static void netvsc_send_vf(struct net_device *ndev, net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated; net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial; + netdev_info(ndev, "VF slot %u %s\n", + net_device_ctx->vf_serial, + net_device_ctx->vf_alloc ? "added" : "removed"); } static void netvsc_receive_inband(struct net_device *ndev, @@ -1220,12 +1230,13 @@ static void netvsc_receive_inband(struct net_device *ndev, } static int netvsc_process_raw_pkt(struct hv_device *device, - struct vmbus_channel *channel, + struct netvsc_channel *nvchan, struct netvsc_device *net_device, struct net_device *ndev, const struct vmpacket_descriptor *desc, int budget) { + struct vmbus_channel *channel = nvchan->channel; const struct nvsp_message *nvmsg = hv_pkt_data(desc); trace_nvsp_recv(ndev, channel, nvmsg); @@ -1237,7 +1248,7 @@ static int netvsc_process_raw_pkt(struct hv_device *device, break; case VM_PKT_DATA_USING_XFER_PAGES: - return netvsc_receive(ndev, net_device, channel, + return netvsc_receive(ndev, net_device, nvchan, desc, nvmsg); break; @@ -1281,7 +1292,7 @@ int netvsc_poll(struct napi_struct *napi, int budget) nvchan->desc = hv_pkt_iter_first(channel); while (nvchan->desc && work_done < budget) { - work_done += netvsc_process_raw_pkt(device, channel, net_device, + work_done += netvsc_process_raw_pkt(device, nvchan, net_device, ndev, nvchan->desc, budget); nvchan->desc = hv_pkt_iter_next(channel, nvchan->desc); } |