]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/net/hyperv/netvsc.c
Merge tag 'jfs-for-4.20' of git://github.com/kleikamp/linux-shaggy
[linux.git] / drivers / net / hyperv / netvsc.c
index fe01e141c8f87d50e42a5cb2670ff5ba4921744a..922054c1d5448bf6406742c52a94a7bc4226575c 100644 (file)
@@ -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;
@@ -1223,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);
@@ -1240,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;
 
@@ -1284,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);
        }