d384c0ddf06916275a666ea8b8fa8bf054b2c258
[safe/jmp/linux-2.6] / drivers / staging / hv / NetVsc.c
1 /*
2  * Copyright (c) 2009, Microsoft Corporation.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15  * Place - Suite 330, Boston, MA 02111-1307 USA.
16  *
17  * Authors:
18  *   Hank Janssen  <hjanssen@microsoft.com>
19  */
20 #include <linux/kernel.h>
21 #include <linux/mm.h>
22 #include <linux/delay.h>
23 #include <linux/io.h>
24 #include "osd.h"
25 #include "logging.h"
26 #include "NetVsc.h"
27 #include "RndisFilter.h"
28
29
30 /* Globals */
31 static const char *gDriverName = "netvsc";
32
33 /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
34 static const struct hv_guid gNetVscDeviceType = {
35         .data = {
36                 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
37                 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
38         }
39 };
40
41 static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo);
42
43 static int NetVscOnDeviceRemove(struct hv_device *Device);
44
45 static void NetVscOnCleanup(struct hv_driver *Driver);
46
47 static void NetVscOnChannelCallback(void *context);
48
49 static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device);
50
51 static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device);
52
53 static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice);
54
55 static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice);
56
57 static int NetVscConnectToVsp(struct hv_device *Device);
58
59 static void NetVscOnSendCompletion(struct hv_device *Device,
60                                    struct vmpacket_descriptor *Packet);
61
62 static int NetVscOnSend(struct hv_device *Device,
63                         struct hv_netvsc_packet *Packet);
64
65 static void NetVscOnReceive(struct hv_device *Device,
66                             struct vmpacket_descriptor *Packet);
67
68 static void NetVscOnReceiveCompletion(void *Context);
69
70 static void NetVscSendReceiveCompletion(struct hv_device *Device,
71                                         u64 TransactionId);
72
73
74 static struct netvsc_device *AllocNetDevice(struct hv_device *Device)
75 {
76         struct netvsc_device *netDevice;
77
78         netDevice = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
79         if (!netDevice)
80                 return NULL;
81
82         /* Set to 2 to allow both inbound and outbound traffic */
83         atomic_cmpxchg(&netDevice->RefCount, 0, 2);
84
85         netDevice->Device = Device;
86         Device->Extension = netDevice;
87
88         return netDevice;
89 }
90
91 static void FreeNetDevice(struct netvsc_device *Device)
92 {
93         ASSERT(atomic_read(&Device->RefCount) == 0);
94         Device->Device->Extension = NULL;
95         kfree(Device);
96 }
97
98
99 /* Get the net device object iff exists and its refcount > 1 */
100 static struct netvsc_device *GetOutboundNetDevice(struct hv_device *Device)
101 {
102         struct netvsc_device *netDevice;
103
104         netDevice = Device->Extension;
105         if (netDevice && atomic_read(&netDevice->RefCount) > 1)
106                 atomic_inc(&netDevice->RefCount);
107         else
108                 netDevice = NULL;
109
110         return netDevice;
111 }
112
113 /* Get the net device object iff exists and its refcount > 0 */
114 static struct netvsc_device *GetInboundNetDevice(struct hv_device *Device)
115 {
116         struct netvsc_device *netDevice;
117
118         netDevice = Device->Extension;
119         if (netDevice && atomic_read(&netDevice->RefCount))
120                 atomic_inc(&netDevice->RefCount);
121         else
122                 netDevice = NULL;
123
124         return netDevice;
125 }
126
127 static void PutNetDevice(struct hv_device *Device)
128 {
129         struct netvsc_device *netDevice;
130
131         netDevice = Device->Extension;
132         ASSERT(netDevice);
133
134         atomic_dec(&netDevice->RefCount);
135 }
136
137 static struct netvsc_device *ReleaseOutboundNetDevice(struct hv_device *Device)
138 {
139         struct netvsc_device *netDevice;
140
141         netDevice = Device->Extension;
142         if (netDevice == NULL)
143                 return NULL;
144
145         /* Busy wait until the ref drop to 2, then set it to 1 */
146         while (atomic_cmpxchg(&netDevice->RefCount, 2, 1) != 2)
147                 udelay(100);
148
149         return netDevice;
150 }
151
152 static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *Device)
153 {
154         struct netvsc_device *netDevice;
155
156         netDevice = Device->Extension;
157         if (netDevice == NULL)
158                 return NULL;
159
160         /* Busy wait until the ref drop to 1, then set it to 0 */
161         while (atomic_cmpxchg(&netDevice->RefCount, 1, 0) != 1)
162                 udelay(100);
163
164         Device->Extension = NULL;
165         return netDevice;
166 }
167
168 /**
169  * NetVscInitialize - Main entry point
170  */
171 int NetVscInitialize(struct hv_driver *drv)
172 {
173         struct netvsc_driver *driver = (struct netvsc_driver *)drv;
174
175         DPRINT_ENTER(NETVSC);
176
177         DPRINT_DBG(NETVSC, "sizeof(struct hv_netvsc_packet)=%zd, "
178                    "sizeof(struct nvsp_message)=%zd, "
179                    "sizeof(struct vmtransfer_page_packet_header)=%zd",
180                    sizeof(struct hv_netvsc_packet),
181                    sizeof(struct nvsp_message),
182                    sizeof(struct vmtransfer_page_packet_header));
183
184         /* Make sure we are at least 2 pages since 1 page is used for control */
185         ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1));
186
187         drv->name = gDriverName;
188         memcpy(&drv->deviceType, &gNetVscDeviceType, sizeof(struct hv_guid));
189
190         /* Make sure it is set by the caller */
191         ASSERT(driver->OnReceiveCallback);
192         ASSERT(driver->OnLinkStatusChanged);
193
194         /* Setup the dispatch table */
195         driver->Base.OnDeviceAdd        = NetVscOnDeviceAdd;
196         driver->Base.OnDeviceRemove     = NetVscOnDeviceRemove;
197         driver->Base.OnCleanup          = NetVscOnCleanup;
198
199         driver->OnSend                  = NetVscOnSend;
200
201         RndisFilterInit(driver);
202
203         DPRINT_EXIT(NETVSC);
204
205         return 0;
206 }
207
208 static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device)
209 {
210         int ret = 0;
211         struct netvsc_device *netDevice;
212         struct nvsp_message *initPacket;
213
214         DPRINT_ENTER(NETVSC);
215
216         netDevice = GetOutboundNetDevice(Device);
217         if (!netDevice) {
218                 DPRINT_ERR(NETVSC, "unable to get net device..."
219                            "device being destroyed?");
220                 DPRINT_EXIT(NETVSC);
221                 return -1;
222         }
223         ASSERT(netDevice->ReceiveBufferSize > 0);
224         /* page-size grandularity */
225         ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0);
226
227         netDevice->ReceiveBuffer =
228                 osd_PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT);
229         if (!netDevice->ReceiveBuffer) {
230                 DPRINT_ERR(NETVSC,
231                            "unable to allocate receive buffer of size %d",
232                            netDevice->ReceiveBufferSize);
233                 ret = -1;
234                 goto Cleanup;
235         }
236         /* page-aligned buffer */
237         ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) ==
238                 0);
239
240         DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL...");
241
242         /*
243          * Establish the gpadl handle for this buffer on this
244          * channel.  Note: This call uses the vmbus connection rather
245          * than the channel to establish the gpadl handle.
246          */
247         ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device,
248                                         netDevice->ReceiveBuffer,
249                                         netDevice->ReceiveBufferSize,
250                                         &netDevice->ReceiveBufferGpadlHandle);
251         if (ret != 0) {
252                 DPRINT_ERR(NETVSC,
253                            "unable to establish receive buffer's gpadl");
254                 goto Cleanup;
255         }
256
257         /* osd_WaitEventWait(ext->ChannelInitEvent); */
258
259         /* Notify the NetVsp of the gpadl handle */
260         DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer...");
261
262         initPacket = &netDevice->ChannelInitPacket;
263
264         memset(initPacket, 0, sizeof(struct nvsp_message));
265
266         initPacket->Header.MessageType = NvspMessage1TypeSendReceiveBuffer;
267         initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->ReceiveBufferGpadlHandle;
268         initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID;
269
270         /* Send the gpadl notification request */
271         ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
272                                 initPacket,
273                                 sizeof(struct nvsp_message),
274                                 (unsigned long)initPacket,
275                                 VmbusPacketTypeDataInBand,
276                                 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
277         if (ret != 0) {
278                 DPRINT_ERR(NETVSC,
279                            "unable to send receive buffer's gpadl to netvsp");
280                 goto Cleanup;
281         }
282
283         osd_WaitEventWait(netDevice->ChannelInitEvent);
284
285         /* Check the response */
286         if (initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status != NvspStatusSuccess) {
287                 DPRINT_ERR(NETVSC, "Unable to complete receive buffer "
288                            "initialzation with NetVsp - status %d",
289                            initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status);
290                 ret = -1;
291                 goto Cleanup;
292         }
293
294         /* Parse the response */
295         ASSERT(netDevice->ReceiveSectionCount == 0);
296         ASSERT(netDevice->ReceiveSections == NULL);
297
298         netDevice->ReceiveSectionCount = initPacket->Messages.Version1Messages.SendReceiveBufferComplete.NumSections;
299
300         netDevice->ReceiveSections = kmalloc(netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL);
301         if (netDevice->ReceiveSections == NULL) {
302                 ret = -1;
303                 goto Cleanup;
304         }
305
306         memcpy(netDevice->ReceiveSections,
307                 initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Sections,
308                 netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section));
309
310         DPRINT_INFO(NETVSC, "Receive sections info (count %d, offset %d, "
311                     "endoffset %d, suballoc size %d, num suballocs %d)",
312                     netDevice->ReceiveSectionCount,
313                     netDevice->ReceiveSections[0].Offset,
314                     netDevice->ReceiveSections[0].EndOffset,
315                     netDevice->ReceiveSections[0].SubAllocationSize,
316                     netDevice->ReceiveSections[0].NumSubAllocations);
317
318         /*
319          * For 1st release, there should only be 1 section that represents the
320          * entire receive buffer
321          */
322         if (netDevice->ReceiveSectionCount != 1 ||
323             netDevice->ReceiveSections->Offset != 0) {
324                 ret = -1;
325                 goto Cleanup;
326         }
327
328         goto Exit;
329
330 Cleanup:
331         NetVscDestroyReceiveBuffer(netDevice);
332
333 Exit:
334         PutNetDevice(Device);
335         DPRINT_EXIT(NETVSC);
336         return ret;
337 }
338
339 static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device)
340 {
341         int ret = 0;
342         struct netvsc_device *netDevice;
343         struct nvsp_message *initPacket;
344
345         DPRINT_ENTER(NETVSC);
346
347         netDevice = GetOutboundNetDevice(Device);
348         if (!netDevice) {
349                 DPRINT_ERR(NETVSC, "unable to get net device..."
350                            "device being destroyed?");
351                 DPRINT_EXIT(NETVSC);
352                 return -1;
353         }
354         ASSERT(netDevice->SendBufferSize > 0);
355         /* page-size grandularity */
356         ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0);
357
358         netDevice->SendBuffer =
359                 osd_PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT);
360         if (!netDevice->SendBuffer) {
361                 DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d",
362                            netDevice->SendBufferSize);
363                 ret = -1;
364                 goto Cleanup;
365         }
366         /* page-aligned buffer */
367         ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0);
368
369         DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL...");
370
371         /*
372          * Establish the gpadl handle for this buffer on this
373          * channel.  Note: This call uses the vmbus connection rather
374          * than the channel to establish the gpadl handle.
375          */
376         ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device,
377                                         netDevice->SendBuffer,
378                                         netDevice->SendBufferSize,
379                                         &netDevice->SendBufferGpadlHandle);
380         if (ret != 0) {
381                 DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl");
382                 goto Cleanup;
383         }
384
385         /* osd_WaitEventWait(ext->ChannelInitEvent); */
386
387         /* Notify the NetVsp of the gpadl handle */
388         DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer...");
389
390         initPacket = &netDevice->ChannelInitPacket;
391
392         memset(initPacket, 0, sizeof(struct nvsp_message));
393
394         initPacket->Header.MessageType = NvspMessage1TypeSendSendBuffer;
395         initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->SendBufferGpadlHandle;
396         initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_SEND_BUFFER_ID;
397
398         /* Send the gpadl notification request */
399         ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
400                                 initPacket, sizeof(struct nvsp_message),
401                                 (unsigned long)initPacket,
402                                 VmbusPacketTypeDataInBand,
403                                 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
404         if (ret != 0) {
405                 DPRINT_ERR(NETVSC,
406                            "unable to send receive buffer's gpadl to netvsp");
407                 goto Cleanup;
408         }
409
410         osd_WaitEventWait(netDevice->ChannelInitEvent);
411
412         /* Check the response */
413         if (initPacket->Messages.Version1Messages.SendSendBufferComplete.Status != NvspStatusSuccess) {
414                 DPRINT_ERR(NETVSC, "Unable to complete send buffer "
415                            "initialzation with NetVsp - status %d",
416                            initPacket->Messages.Version1Messages.SendSendBufferComplete.Status);
417                 ret = -1;
418                 goto Cleanup;
419         }
420
421         netDevice->SendSectionSize = initPacket->Messages.Version1Messages.SendSendBufferComplete.SectionSize;
422
423         goto Exit;
424
425 Cleanup:
426         NetVscDestroySendBuffer(netDevice);
427
428 Exit:
429         PutNetDevice(Device);
430         DPRINT_EXIT(NETVSC);
431         return ret;
432 }
433
434 static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice)
435 {
436         struct nvsp_message *revokePacket;
437         int ret = 0;
438
439         DPRINT_ENTER(NETVSC);
440
441         /*
442          * If we got a section count, it means we received a
443          * SendReceiveBufferComplete msg (ie sent
444          * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
445          * to send a revoke msg here
446          */
447         if (NetDevice->ReceiveSectionCount) {
448                 DPRINT_INFO(NETVSC,
449                             "Sending NvspMessage1TypeRevokeReceiveBuffer...");
450
451                 /* Send the revoke receive buffer */
452                 revokePacket = &NetDevice->RevokePacket;
453                 memset(revokePacket, 0, sizeof(struct nvsp_message));
454
455                 revokePacket->Header.MessageType = NvspMessage1TypeRevokeReceiveBuffer;
456                 revokePacket->Messages.Version1Messages.RevokeReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID;
457
458                 ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket(
459                                                 NetDevice->Device,
460                                                 revokePacket,
461                                                 sizeof(struct nvsp_message),
462                                                 (unsigned long)revokePacket,
463                                                 VmbusPacketTypeDataInBand, 0);
464                 /*
465                  * If we failed here, we might as well return and
466                  * have a leak rather than continue and a bugchk
467                  */
468                 if (ret != 0) {
469                         DPRINT_ERR(NETVSC, "unable to send revoke receive "
470                                    "buffer to netvsp");
471                         DPRINT_EXIT(NETVSC);
472                         return -1;
473                 }
474         }
475
476         /* Teardown the gpadl on the vsp end */
477         if (NetDevice->ReceiveBufferGpadlHandle) {
478                 DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL...");
479
480                 ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl(
481                                         NetDevice->Device,
482                                         NetDevice->ReceiveBufferGpadlHandle);
483
484                 /* If we failed here, we might as well return and have a leak rather than continue and a bugchk */
485                 if (ret != 0) {
486                         DPRINT_ERR(NETVSC,
487                                    "unable to teardown receive buffer's gpadl");
488                         DPRINT_EXIT(NETVSC);
489                         return -1;
490                 }
491                 NetDevice->ReceiveBufferGpadlHandle = 0;
492         }
493
494         if (NetDevice->ReceiveBuffer) {
495                 DPRINT_INFO(NETVSC, "Freeing up receive buffer...");
496
497                 /* Free up the receive buffer */
498                 osd_PageFree(NetDevice->ReceiveBuffer,
499                              NetDevice->ReceiveBufferSize >> PAGE_SHIFT);
500                 NetDevice->ReceiveBuffer = NULL;
501         }
502
503         if (NetDevice->ReceiveSections) {
504                 NetDevice->ReceiveSectionCount = 0;
505                 kfree(NetDevice->ReceiveSections);
506                 NetDevice->ReceiveSections = NULL;
507         }
508
509         DPRINT_EXIT(NETVSC);
510
511         return ret;
512 }
513
514 static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice)
515 {
516         struct nvsp_message *revokePacket;
517         int ret = 0;
518
519         DPRINT_ENTER(NETVSC);
520
521         /*
522          * If we got a section count, it means we received a
523          *  SendReceiveBufferComplete msg (ie sent
524          *  NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
525          *  to send a revoke msg here
526          */
527         if (NetDevice->SendSectionSize) {
528                 DPRINT_INFO(NETVSC,
529                             "Sending NvspMessage1TypeRevokeSendBuffer...");
530
531                 /* Send the revoke send buffer */
532                 revokePacket = &NetDevice->RevokePacket;
533                 memset(revokePacket, 0, sizeof(struct nvsp_message));
534
535                 revokePacket->Header.MessageType = NvspMessage1TypeRevokeSendBuffer;
536                 revokePacket->Messages.Version1Messages.RevokeSendBuffer.Id = NETVSC_SEND_BUFFER_ID;
537
538                 ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket(NetDevice->Device,
539                                         revokePacket,
540                                         sizeof(struct nvsp_message),
541                                         (unsigned long)revokePacket,
542                                         VmbusPacketTypeDataInBand, 0);
543                 /*
544                  * If we failed here, we might as well return and have a leak
545                  * rather than continue and a bugchk
546                  */
547                 if (ret != 0) {
548                         DPRINT_ERR(NETVSC, "unable to send revoke send buffer "
549                                    "to netvsp");
550                         DPRINT_EXIT(NETVSC);
551                         return -1;
552                 }
553         }
554
555         /* Teardown the gpadl on the vsp end */
556         if (NetDevice->SendBufferGpadlHandle) {
557                 DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL...");
558
559                 ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl(NetDevice->Device, NetDevice->SendBufferGpadlHandle);
560
561                 /*
562                  * If we failed here, we might as well return and have a leak
563                  * rather than continue and a bugchk
564                  */
565                 if (ret != 0) {
566                         DPRINT_ERR(NETVSC, "unable to teardown send buffer's "
567                                    "gpadl");
568                         DPRINT_EXIT(NETVSC);
569                         return -1;
570                 }
571                 NetDevice->SendBufferGpadlHandle = 0;
572         }
573
574         if (NetDevice->SendBuffer) {
575                 DPRINT_INFO(NETVSC, "Freeing up send buffer...");
576
577                 /* Free up the receive buffer */
578                 osd_PageFree(NetDevice->SendBuffer,
579                              NetDevice->SendBufferSize >> PAGE_SHIFT);
580                 NetDevice->SendBuffer = NULL;
581         }
582
583         DPRINT_EXIT(NETVSC);
584
585         return ret;
586 }
587
588
589 static int NetVscConnectToVsp(struct hv_device *Device)
590 {
591         int ret;
592         struct netvsc_device *netDevice;
593         struct nvsp_message *initPacket;
594         int ndisVersion;
595
596         DPRINT_ENTER(NETVSC);
597
598         netDevice = GetOutboundNetDevice(Device);
599         if (!netDevice) {
600                 DPRINT_ERR(NETVSC, "unable to get net device..."
601                            "device being destroyed?");
602                 DPRINT_EXIT(NETVSC);
603                 return -1;
604         }
605
606         initPacket = &netDevice->ChannelInitPacket;
607
608         memset(initPacket, 0, sizeof(struct nvsp_message));
609         initPacket->Header.MessageType = NvspMessageTypeInit;
610         initPacket->Messages.InitMessages.Init.MinProtocolVersion = NVSP_MIN_PROTOCOL_VERSION;
611         initPacket->Messages.InitMessages.Init.MaxProtocolVersion = NVSP_MAX_PROTOCOL_VERSION;
612
613         DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit...");
614
615         /* Send the init request */
616         ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
617                                 initPacket,
618                                 sizeof(struct nvsp_message),
619                                 (unsigned long)initPacket,
620                                 VmbusPacketTypeDataInBand,
621                                 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
622
623         if (ret != 0) {
624                 DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit");
625                 goto Cleanup;
626         }
627
628         osd_WaitEventWait(netDevice->ChannelInitEvent);
629
630         /* Now, check the response */
631         /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */
632         DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)",
633                 initPacket->Messages.InitMessages.InitComplete.Status,
634                 initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength);
635
636         if (initPacket->Messages.InitMessages.InitComplete.Status !=
637             NvspStatusSuccess) {
638                 DPRINT_ERR(NETVSC,
639                         "unable to initialize with netvsp (status 0x%x)",
640                         initPacket->Messages.InitMessages.InitComplete.Status);
641                 ret = -1;
642                 goto Cleanup;
643         }
644
645         if (initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion != NVSP_PROTOCOL_VERSION_1) {
646                 DPRINT_ERR(NETVSC, "unable to initialize with netvsp "
647                            "(version expected 1 got %d)",
648                            initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion);
649                 ret = -1;
650                 goto Cleanup;
651         }
652         DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion...");
653
654         /* Send the ndis version */
655         memset(initPacket, 0, sizeof(struct nvsp_message));
656
657         ndisVersion = 0x00050000;
658
659         initPacket->Header.MessageType = NvspMessage1TypeSendNdisVersion;
660         initPacket->Messages.Version1Messages.SendNdisVersion.NdisMajorVersion =
661                                 (ndisVersion & 0xFFFF0000) >> 16;
662         initPacket->Messages.Version1Messages.SendNdisVersion.NdisMinorVersion =
663                                 ndisVersion & 0xFFFF;
664
665         /* Send the init request */
666         ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
667                                         initPacket,
668                                         sizeof(struct nvsp_message),
669                                         (unsigned long)initPacket,
670                                         VmbusPacketTypeDataInBand, 0);
671         if (ret != 0) {
672                 DPRINT_ERR(NETVSC,
673                            "unable to send NvspMessage1TypeSendNdisVersion");
674                 ret = -1;
675                 goto Cleanup;
676         }
677         /*
678          * BUGBUG - We have to wait for the above msg since the
679          * netvsp uses KMCL which acknowledges packet (completion
680          * packet) since our Vmbus always set the
681          * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag
682          */
683          /* osd_WaitEventWait(NetVscChannel->ChannelInitEvent); */
684
685         /* Post the big receive buffer to NetVSP */
686         ret = NetVscInitializeReceiveBufferWithNetVsp(Device);
687         if (ret == 0)
688                 ret = NetVscInitializeSendBufferWithNetVsp(Device);
689
690 Cleanup:
691         PutNetDevice(Device);
692         DPRINT_EXIT(NETVSC);
693         return ret;
694 }
695
696 static void NetVscDisconnectFromVsp(struct netvsc_device *NetDevice)
697 {
698         DPRINT_ENTER(NETVSC);
699
700         NetVscDestroyReceiveBuffer(NetDevice);
701         NetVscDestroySendBuffer(NetDevice);
702
703         DPRINT_EXIT(NETVSC);
704 }
705
706 /**
707  * NetVscOnDeviceAdd - Callback when the device belonging to this driver is added
708  */
709 static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
710 {
711         int ret = 0;
712         int i;
713         struct netvsc_device *netDevice;
714         struct hv_netvsc_packet *packet, *pos;
715         struct netvsc_driver *netDriver =
716                                 (struct netvsc_driver *)Device->Driver;
717
718         DPRINT_ENTER(NETVSC);
719
720         netDevice = AllocNetDevice(Device);
721         if (!netDevice) {
722                 ret = -1;
723                 goto Cleanup;
724         }
725
726         DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", netDevice);
727
728         /* Initialize the NetVSC channel extension */
729         netDevice->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE;
730         spin_lock_init(&netDevice->receive_packet_list_lock);
731
732         netDevice->SendBufferSize = NETVSC_SEND_BUFFER_SIZE;
733
734         INIT_LIST_HEAD(&netDevice->ReceivePacketList);
735
736         for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
737                 packet = kzalloc(sizeof(struct hv_netvsc_packet) +
738                                  (NETVSC_RECEIVE_SG_COUNT *
739                                   sizeof(struct hv_page_buffer)), GFP_KERNEL);
740                 if (!packet) {
741                         DPRINT_DBG(NETVSC, "unable to allocate netvsc pkts "
742                                    "for receive pool (wanted %d got %d)",
743                                    NETVSC_RECEIVE_PACKETLIST_COUNT, i);
744                         break;
745                 }
746                 list_add_tail(&packet->ListEntry,
747                               &netDevice->ReceivePacketList);
748         }
749         netDevice->ChannelInitEvent = osd_WaitEventCreate();
750
751         /* Open the channel */
752         ret = Device->Driver->VmbusChannelInterface.Open(Device,
753                                                 netDriver->RingBufferSize,
754                                                 netDriver->RingBufferSize,
755                                                 NULL, 0,
756                                                 NetVscOnChannelCallback,
757                                                 Device);
758
759         if (ret != 0) {
760                 DPRINT_ERR(NETVSC, "unable to open channel: %d", ret);
761                 ret = -1;
762                 goto Cleanup;
763         }
764
765         /* Channel is opened */
766         DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***");
767
768         /* Connect with the NetVsp */
769         ret = NetVscConnectToVsp(Device);
770         if (ret != 0) {
771                 DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret);
772                 ret = -1;
773                 goto Close;
774         }
775
776         DPRINT_INFO(NETVSC, "*** NetVSC channel handshake result - %d ***",
777                     ret);
778
779         DPRINT_EXIT(NETVSC);
780         return ret;
781
782 Close:
783         /* Now, we can close the channel safely */
784         Device->Driver->VmbusChannelInterface.Close(Device);
785
786 Cleanup:
787
788         if (netDevice) {
789                 kfree(netDevice->ChannelInitEvent);
790
791                 list_for_each_entry_safe(packet, pos,
792                                          &netDevice->ReceivePacketList,
793                                          ListEntry) {
794                         list_del(&packet->ListEntry);
795                         kfree(packet);
796                 }
797
798                 ReleaseOutboundNetDevice(Device);
799                 ReleaseInboundNetDevice(Device);
800
801                 FreeNetDevice(netDevice);
802         }
803
804         DPRINT_EXIT(NETVSC);
805         return ret;
806 }
807
808 /**
809  * NetVscOnDeviceRemove - Callback when the root bus device is removed
810  */
811 static int NetVscOnDeviceRemove(struct hv_device *Device)
812 {
813         struct netvsc_device *netDevice;
814         struct hv_netvsc_packet *netvscPacket, *pos;
815
816         DPRINT_ENTER(NETVSC);
817
818         DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...",
819                     Device->Extension);
820
821         /* Stop outbound traffic ie sends and receives completions */
822         netDevice = ReleaseOutboundNetDevice(Device);
823         if (!netDevice) {
824                 DPRINT_ERR(NETVSC, "No net device present!!");
825                 return -1;
826         }
827
828         /* Wait for all send completions */
829         while (atomic_read(&netDevice->NumOutstandingSends)) {
830                 DPRINT_INFO(NETVSC, "waiting for %d requests to complete...",
831                             atomic_read(&netDevice->NumOutstandingSends));
832                 udelay(100);
833         }
834
835         DPRINT_INFO(NETVSC, "Disconnecting from netvsp...");
836
837         NetVscDisconnectFromVsp(netDevice);
838
839         DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...",
840                     Device->Extension);
841
842         /* Stop inbound traffic ie receives and sends completions */
843         netDevice = ReleaseInboundNetDevice(Device);
844
845         /* At this point, no one should be accessing netDevice except in here */
846         DPRINT_INFO(NETVSC, "net device (%p) safe to remove", netDevice);
847
848         /* Now, we can close the channel safely */
849         Device->Driver->VmbusChannelInterface.Close(Device);
850
851         /* Release all resources */
852         list_for_each_entry_safe(netvscPacket, pos,
853                                  &netDevice->ReceivePacketList, ListEntry) {
854                 list_del(&netvscPacket->ListEntry);
855                 kfree(netvscPacket);
856         }
857
858         kfree(netDevice->ChannelInitEvent);
859         FreeNetDevice(netDevice);
860
861         DPRINT_EXIT(NETVSC);
862         return 0;
863 }
864
865 /**
866  * NetVscOnCleanup - Perform any cleanup when the driver is removed
867  */
868 static void NetVscOnCleanup(struct hv_driver *drv)
869 {
870         DPRINT_ENTER(NETVSC);
871         DPRINT_EXIT(NETVSC);
872 }
873
874 static void NetVscOnSendCompletion(struct hv_device *Device,
875                                    struct vmpacket_descriptor *Packet)
876 {
877         struct netvsc_device *netDevice;
878         struct nvsp_message *nvspPacket;
879         struct hv_netvsc_packet *nvscPacket;
880
881         DPRINT_ENTER(NETVSC);
882
883         netDevice = GetInboundNetDevice(Device);
884         if (!netDevice) {
885                 DPRINT_ERR(NETVSC, "unable to get net device..."
886                            "device being destroyed?");
887                 DPRINT_EXIT(NETVSC);
888                 return;
889         }
890
891         nvspPacket = (struct nvsp_message *)((unsigned long)Packet + (Packet->DataOffset8 << 3));
892
893         DPRINT_DBG(NETVSC, "send completion packet - type %d",
894                    nvspPacket->Header.MessageType);
895
896         if ((nvspPacket->Header.MessageType == NvspMessageTypeInitComplete) ||
897             (nvspPacket->Header.MessageType ==
898              NvspMessage1TypeSendReceiveBufferComplete) ||
899             (nvspPacket->Header.MessageType ==
900              NvspMessage1TypeSendSendBufferComplete)) {
901                 /* Copy the response back */
902                 memcpy(&netDevice->ChannelInitPacket, nvspPacket,
903                        sizeof(struct nvsp_message));
904                 osd_WaitEventSet(netDevice->ChannelInitEvent);
905         } else if (nvspPacket->Header.MessageType ==
906                    NvspMessage1TypeSendRNDISPacketComplete) {
907                 /* Get the send context */
908                 nvscPacket = (struct hv_netvsc_packet *)(unsigned long)Packet->TransactionId;
909                 ASSERT(nvscPacket);
910
911                 /* Notify the layer above us */
912                 nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext);
913
914                 atomic_dec(&netDevice->NumOutstandingSends);
915         } else {
916                 DPRINT_ERR(NETVSC, "Unknown send completion packet type - "
917                            "%d received!!", nvspPacket->Header.MessageType);
918         }
919
920         PutNetDevice(Device);
921         DPRINT_EXIT(NETVSC);
922 }
923
924 static int NetVscOnSend(struct hv_device *Device,
925                         struct hv_netvsc_packet *Packet)
926 {
927         struct netvsc_device *netDevice;
928         int ret = 0;
929
930         struct nvsp_message sendMessage;
931
932         DPRINT_ENTER(NETVSC);
933
934         netDevice = GetOutboundNetDevice(Device);
935         if (!netDevice) {
936                 DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
937                            "ignoring outbound packets", netDevice);
938                 DPRINT_EXIT(NETVSC);
939                 return -2;
940         }
941
942         sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket;
943         if (Packet->IsDataPacket) {
944                 /* 0 is RMC_DATA; */
945                 sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0;
946         } else {
947                 /* 1 is RMC_CONTROL; */
948                 sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 1;
949         }
950
951         /* Not using send buffer section */
952         sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF;
953         sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0;
954
955         if (Packet->PageBufferCount) {
956                 ret = Device->Driver->VmbusChannelInterface.SendPacketPageBuffer(
957                                         Device, Packet->PageBuffers,
958                                         Packet->PageBufferCount,
959                                         &sendMessage,
960                                         sizeof(struct nvsp_message),
961                                         (unsigned long)Packet);
962         } else {
963                 ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
964                                 &sendMessage,
965                                 sizeof(struct nvsp_message),
966                                 (unsigned long)Packet,
967                                 VmbusPacketTypeDataInBand,
968                                 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
969
970         }
971
972         if (ret != 0)
973                 DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d",
974                            Packet, ret);
975
976         atomic_inc(&netDevice->NumOutstandingSends);
977         PutNetDevice(Device);
978
979         DPRINT_EXIT(NETVSC);
980         return ret;
981 }
982
983 static void NetVscOnReceive(struct hv_device *Device,
984                             struct vmpacket_descriptor *Packet)
985 {
986         struct netvsc_device *netDevice;
987         struct vmtransfer_page_packet_header *vmxferpagePacket;
988         struct nvsp_message *nvspPacket;
989         struct hv_netvsc_packet *netvscPacket = NULL;
990         unsigned long start;
991         unsigned long end, endVirtual;
992         /* struct netvsc_driver *netvscDriver; */
993         struct xferpage_packet *xferpagePacket = NULL;
994         int i, j;
995         int count = 0, bytesRemain = 0;
996         unsigned long flags;
997         LIST_HEAD(listHead);
998
999         DPRINT_ENTER(NETVSC);
1000
1001         netDevice = GetInboundNetDevice(Device);
1002         if (!netDevice) {
1003                 DPRINT_ERR(NETVSC, "unable to get net device..."
1004                            "device being destroyed?");
1005                 DPRINT_EXIT(NETVSC);
1006                 return;
1007         }
1008
1009         /*
1010          * All inbound packets other than send completion should be xfer page
1011          * packet
1012          */
1013         if (Packet->Type != VmbusPacketTypeDataUsingTransferPages) {
1014                 DPRINT_ERR(NETVSC, "Unknown packet type received - %d",
1015                            Packet->Type);
1016                 PutNetDevice(Device);
1017                 return;
1018         }
1019
1020         nvspPacket = (struct nvsp_message *)((unsigned long)Packet +
1021                         (Packet->DataOffset8 << 3));
1022
1023         /* Make sure this is a valid nvsp packet */
1024         if (nvspPacket->Header.MessageType != NvspMessage1TypeSendRNDISPacket) {
1025                 DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d",
1026                            nvspPacket->Header.MessageType);
1027                 PutNetDevice(Device);
1028                 return;
1029         }
1030
1031         DPRINT_DBG(NETVSC, "NVSP packet received - type %d",
1032                    nvspPacket->Header.MessageType);
1033
1034         vmxferpagePacket = (struct vmtransfer_page_packet_header *)Packet;
1035
1036         if (vmxferpagePacket->TransferPageSetId != NETVSC_RECEIVE_BUFFER_ID) {
1037                 DPRINT_ERR(NETVSC, "Invalid xfer page set id - "
1038                            "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID,
1039                            vmxferpagePacket->TransferPageSetId);
1040                 PutNetDevice(Device);
1041                 return;
1042         }
1043
1044         DPRINT_DBG(NETVSC, "xfer page - range count %d",
1045                    vmxferpagePacket->RangeCount);
1046
1047         /*
1048          * Grab free packets (range count + 1) to represent this xfer
1049          * page packet. +1 to represent the xfer page packet itself.
1050          * We grab it here so that we know exactly how many we can
1051          * fulfil
1052          */
1053         spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
1054         while (!list_empty(&netDevice->ReceivePacketList)) {
1055                 list_move_tail(netDevice->ReceivePacketList.next, &listHead);
1056                 if (++count == vmxferpagePacket->RangeCount + 1)
1057                         break;
1058         }
1059         spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags);
1060
1061         /*
1062          * We need at least 2 netvsc pkts (1 to represent the xfer
1063          * page and at least 1 for the range) i.e. we can handled
1064          * some of the xfer page packet ranges...
1065          */
1066         if (count < 2) {
1067                 DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. "
1068                            "Dropping this xfer page packet completely!",
1069                            count, vmxferpagePacket->RangeCount + 1);
1070
1071                 /* Return it to the freelist */
1072                 spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
1073                 for (i = count; i != 0; i--) {
1074                         list_move_tail(listHead.next,
1075                                        &netDevice->ReceivePacketList);
1076                 }
1077                 spin_unlock_irqrestore(&netDevice->receive_packet_list_lock,
1078                                        flags);
1079
1080                 NetVscSendReceiveCompletion(Device,
1081                                             vmxferpagePacket->d.TransactionId);
1082
1083                 PutNetDevice(Device);
1084                 return;
1085         }
1086
1087         /* Remove the 1st packet to represent the xfer page packet itself */
1088         xferpagePacket = (struct xferpage_packet*)listHead.next;
1089         list_del(&xferpagePacket->ListEntry);
1090
1091         /* This is how much we can satisfy */
1092         xferpagePacket->Count = count - 1;
1093         ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <=
1094                 vmxferpagePacket->RangeCount);
1095
1096         if (xferpagePacket->Count != vmxferpagePacket->RangeCount) {
1097                 DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer "
1098                             "page...got %d", vmxferpagePacket->RangeCount,
1099                             xferpagePacket->Count);
1100         }
1101
1102         /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
1103         for (i = 0; i < (count - 1); i++) {
1104                 netvscPacket = (struct hv_netvsc_packet*)listHead.next;
1105                 list_del(&netvscPacket->ListEntry);
1106
1107                 /* Initialize the netvsc packet */
1108                 netvscPacket->XferPagePacket = xferpagePacket;
1109                 netvscPacket->Completion.Recv.OnReceiveCompletion =
1110                                         NetVscOnReceiveCompletion;
1111                 netvscPacket->Completion.Recv.ReceiveCompletionContext =
1112                                         netvscPacket;
1113                 netvscPacket->Device = Device;
1114                 /* Save this so that we can send it back */
1115                 netvscPacket->Completion.Recv.ReceiveCompletionTid =
1116                                         vmxferpagePacket->d.TransactionId;
1117
1118                 netvscPacket->TotalDataBufferLength =
1119                                         vmxferpagePacket->Ranges[i].ByteCount;
1120                 netvscPacket->PageBufferCount = 1;
1121
1122                 ASSERT(vmxferpagePacket->Ranges[i].ByteOffset +
1123                         vmxferpagePacket->Ranges[i].ByteCount <
1124                         netDevice->ReceiveBufferSize);
1125
1126                 netvscPacket->PageBuffers[0].Length =
1127                                         vmxferpagePacket->Ranges[i].ByteCount;
1128
1129                 start = virt_to_phys((void *)((unsigned long)netDevice->ReceiveBuffer + vmxferpagePacket->Ranges[i].ByteOffset));
1130
1131                 netvscPacket->PageBuffers[0].Pfn = start >> PAGE_SHIFT;
1132                 endVirtual = (unsigned long)netDevice->ReceiveBuffer
1133                     + vmxferpagePacket->Ranges[i].ByteOffset
1134                     + vmxferpagePacket->Ranges[i].ByteCount - 1;
1135                 end = virt_to_phys((void *)endVirtual);
1136
1137                 /* Calculate the page relative offset */
1138                 netvscPacket->PageBuffers[0].Offset =
1139                         vmxferpagePacket->Ranges[i].ByteOffset & (PAGE_SIZE - 1);
1140                 if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) {
1141                         /* Handle frame across multiple pages: */
1142                         netvscPacket->PageBuffers[0].Length =
1143                                 (netvscPacket->PageBuffers[0].Pfn << PAGE_SHIFT)
1144                                 + PAGE_SIZE - start;
1145                         bytesRemain = netvscPacket->TotalDataBufferLength -
1146                                         netvscPacket->PageBuffers[0].Length;
1147                         for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) {
1148                                 netvscPacket->PageBuffers[j].Offset = 0;
1149                                 if (bytesRemain <= PAGE_SIZE) {
1150                                         netvscPacket->PageBuffers[j].Length = bytesRemain;
1151                                         bytesRemain = 0;
1152                                 } else {
1153                                         netvscPacket->PageBuffers[j].Length = PAGE_SIZE;
1154                                         bytesRemain -= PAGE_SIZE;
1155                                 }
1156                                 netvscPacket->PageBuffers[j].Pfn =
1157                                     virt_to_phys((void *)(endVirtual - bytesRemain)) >> PAGE_SHIFT;
1158                                 netvscPacket->PageBufferCount++;
1159                                 if (bytesRemain == 0)
1160                                         break;
1161                         }
1162                         ASSERT(bytesRemain == 0);
1163                 }
1164                 DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => "
1165                            "(pfn %llx, offset %u, len %u)", i,
1166                            vmxferpagePacket->Ranges[i].ByteOffset,
1167                            vmxferpagePacket->Ranges[i].ByteCount,
1168                            netvscPacket->PageBuffers[0].Pfn,
1169                            netvscPacket->PageBuffers[0].Offset,
1170                            netvscPacket->PageBuffers[0].Length);
1171
1172                 /* Pass it to the upper layer */
1173                 ((struct netvsc_driver *)Device->Driver)->OnReceiveCallback(Device, netvscPacket);
1174
1175                 NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext);
1176         }
1177
1178         ASSERT(list_empty(&listHead));
1179
1180         PutNetDevice(Device);
1181         DPRINT_EXIT(NETVSC);
1182 }
1183
1184 static void NetVscSendReceiveCompletion(struct hv_device *Device,
1185                                         u64 TransactionId)
1186 {
1187         struct nvsp_message recvcompMessage;
1188         int retries = 0;
1189         int ret;
1190
1191         DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx",
1192                    TransactionId);
1193
1194         recvcompMessage.Header.MessageType =
1195                                 NvspMessage1TypeSendRNDISPacketComplete;
1196
1197         /* FIXME: Pass in the status */
1198         recvcompMessage.Messages.Version1Messages.SendRNDISPacketComplete.Status = NvspStatusSuccess;
1199
1200 retry_send_cmplt:
1201         /* Send the completion */
1202         ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
1203                                         &recvcompMessage,
1204                                         sizeof(struct nvsp_message),
1205                                         TransactionId,
1206                                         VmbusPacketTypeCompletion, 0);
1207         if (ret == 0) {
1208                 /* success */
1209                 /* no-op */
1210         } else if (ret == -1) {
1211                 /* no more room...wait a bit and attempt to retry 3 times */
1212                 retries++;
1213                 DPRINT_ERR(NETVSC, "unable to send receive completion pkt "
1214                            "(tid %llx)...retrying %d", TransactionId, retries);
1215
1216                 if (retries < 4) {
1217                         udelay(100);
1218                         goto retry_send_cmplt;
1219                 } else {
1220                         DPRINT_ERR(NETVSC, "unable to send receive completion "
1221                                   "pkt (tid %llx)...give up retrying",
1222                                   TransactionId);
1223                 }
1224         } else {
1225                 DPRINT_ERR(NETVSC, "unable to send receive completion pkt - "
1226                            "%llx", TransactionId);
1227         }
1228 }
1229
1230 /* Send a receive completion packet to RNDIS device (ie NetVsp) */
1231 static void NetVscOnReceiveCompletion(void *Context)
1232 {
1233         struct hv_netvsc_packet *packet = Context;
1234         struct hv_device *device = (struct hv_device *)packet->Device;
1235         struct netvsc_device *netDevice;
1236         u64 transactionId = 0;
1237         bool fSendReceiveComp = false;
1238         unsigned long flags;
1239
1240         DPRINT_ENTER(NETVSC);
1241
1242         ASSERT(packet->XferPagePacket);
1243
1244         /*
1245          * Even though it seems logical to do a GetOutboundNetDevice() here to
1246          * send out receive completion, we are using GetInboundNetDevice()
1247          * since we may have disable outbound traffic already.
1248          */
1249         netDevice = GetInboundNetDevice(device);
1250         if (!netDevice) {
1251                 DPRINT_ERR(NETVSC, "unable to get net device..."
1252                            "device being destroyed?");
1253                 DPRINT_EXIT(NETVSC);
1254                 return;
1255         }
1256
1257         /* Overloading use of the lock. */
1258         spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
1259
1260         ASSERT(packet->XferPagePacket->Count > 0);
1261         packet->XferPagePacket->Count--;
1262
1263         /*
1264          * Last one in the line that represent 1 xfer page packet.
1265          * Return the xfer page packet itself to the freelist
1266          */
1267         if (packet->XferPagePacket->Count == 0) {
1268                 fSendReceiveComp = true;
1269                 transactionId = packet->Completion.Recv.ReceiveCompletionTid;
1270                 list_add_tail(&packet->XferPagePacket->ListEntry,
1271                               &netDevice->ReceivePacketList);
1272
1273         }
1274
1275         /* Put the packet back */
1276         list_add_tail(&packet->ListEntry, &netDevice->ReceivePacketList);
1277         spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags);
1278
1279         /* Send a receive completion for the xfer page packet */
1280         if (fSendReceiveComp)
1281                 NetVscSendReceiveCompletion(device, transactionId);
1282
1283         PutNetDevice(device);
1284         DPRINT_EXIT(NETVSC);
1285 }
1286
1287 void NetVscOnChannelCallback(void *Context)
1288 {
1289         const int netPacketSize = 2048;
1290         int ret;
1291         struct hv_device *device = Context;
1292         struct netvsc_device *netDevice;
1293         u32 bytesRecvd;
1294         u64 requestId;
1295         unsigned char packet[netPacketSize];
1296         struct vmpacket_descriptor *desc;
1297         unsigned char *buffer = packet;
1298         int bufferlen = netPacketSize;
1299
1300
1301         DPRINT_ENTER(NETVSC);
1302
1303         ASSERT(device);
1304
1305         netDevice = GetInboundNetDevice(device);
1306         if (!netDevice) {
1307                 DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
1308                            "ignoring inbound packets", netDevice);
1309                 DPRINT_EXIT(NETVSC);
1310                 return;
1311         }
1312
1313         do {
1314                 ret = device->Driver->VmbusChannelInterface.RecvPacketRaw(
1315                                                 device, buffer, bufferlen,
1316                                                 &bytesRecvd, &requestId);
1317                 if (ret == 0) {
1318                         if (bytesRecvd > 0) {
1319                                 DPRINT_DBG(NETVSC, "receive %d bytes, tid %llx",
1320                                            bytesRecvd, requestId);
1321
1322                                 desc = (struct vmpacket_descriptor *)buffer;
1323                                 switch (desc->Type) {
1324                                 case VmbusPacketTypeCompletion:
1325                                         NetVscOnSendCompletion(device, desc);
1326                                         break;
1327
1328                                 case VmbusPacketTypeDataUsingTransferPages:
1329                                         NetVscOnReceive(device, desc);
1330                                         break;
1331
1332                                 default:
1333                                         DPRINT_ERR(NETVSC,
1334                                                    "unhandled packet type %d, "
1335                                                    "tid %llx len %d\n",
1336                                                    desc->Type, requestId,
1337                                                    bytesRecvd);
1338                                         break;
1339                                 }
1340
1341                                 /* reset */
1342                                 if (bufferlen > netPacketSize) {
1343                                         kfree(buffer);
1344                                         buffer = packet;
1345                                         bufferlen = netPacketSize;
1346                                 }
1347                         } else {
1348                                 /* reset */
1349                                 if (bufferlen > netPacketSize) {
1350                                         kfree(buffer);
1351                                         buffer = packet;
1352                                         bufferlen = netPacketSize;
1353                                 }
1354
1355                                 break;
1356                         }
1357                 } else if (ret == -2) {
1358                         /* Handle large packet */
1359                         buffer = kmalloc(bytesRecvd, GFP_ATOMIC);
1360                         if (buffer == NULL) {
1361                                 /* Try again next time around */
1362                                 DPRINT_ERR(NETVSC,
1363                                            "unable to allocate buffer of size "
1364                                            "(%d)!!", bytesRecvd);
1365                                 break;
1366                         }
1367
1368                         bufferlen = bytesRecvd;
1369                 } else {
1370                         ASSERT(0);
1371                 }
1372         } while (1);
1373
1374         PutNetDevice(device);
1375         DPRINT_EXIT(NETVSC);
1376         return;
1377 }