Staging: hv: rename struct NETVSC_DEVICE
[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;
715         LIST_ENTRY *entry;
716         struct netvsc_driver *netDriver =
717                                 (struct netvsc_driver *)Device->Driver;
718
719         DPRINT_ENTER(NETVSC);
720
721         netDevice = AllocNetDevice(Device);
722         if (!netDevice) {
723                 ret = -1;
724                 goto Cleanup;
725         }
726
727         DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", netDevice);
728
729         /* Initialize the NetVSC channel extension */
730         netDevice->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE;
731         spin_lock_init(&netDevice->receive_packet_list_lock);
732
733         netDevice->SendBufferSize = NETVSC_SEND_BUFFER_SIZE;
734
735         INITIALIZE_LIST_HEAD(&netDevice->ReceivePacketList);
736
737         for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
738                 packet = kzalloc(sizeof(struct hv_netvsc_packet) +
739                                  (NETVSC_RECEIVE_SG_COUNT *
740                                   sizeof(struct hv_page_buffer)), GFP_KERNEL);
741                 if (!packet) {
742                         DPRINT_DBG(NETVSC, "unable to allocate netvsc pkts "
743                                    "for receive pool (wanted %d got %d)",
744                                    NETVSC_RECEIVE_PACKETLIST_COUNT, i);
745                         break;
746                 }
747
748                 INSERT_TAIL_LIST(&netDevice->ReceivePacketList,
749                                  &packet->ListEntry);
750         }
751         netDevice->ChannelInitEvent = osd_WaitEventCreate();
752
753         /* Open the channel */
754         ret = Device->Driver->VmbusChannelInterface.Open(Device,
755                                                 netDriver->RingBufferSize,
756                                                 netDriver->RingBufferSize,
757                                                 NULL, 0,
758                                                 NetVscOnChannelCallback,
759                                                 Device);
760
761         if (ret != 0) {
762                 DPRINT_ERR(NETVSC, "unable to open channel: %d", ret);
763                 ret = -1;
764                 goto Cleanup;
765         }
766
767         /* Channel is opened */
768         DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***");
769
770         /* Connect with the NetVsp */
771         ret = NetVscConnectToVsp(Device);
772         if (ret != 0) {
773                 DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret);
774                 ret = -1;
775                 goto Close;
776         }
777
778         DPRINT_INFO(NETVSC, "*** NetVSC channel handshake result - %d ***",
779                     ret);
780
781         DPRINT_EXIT(NETVSC);
782         return ret;
783
784 Close:
785         /* Now, we can close the channel safely */
786         Device->Driver->VmbusChannelInterface.Close(Device);
787
788 Cleanup:
789
790         if (netDevice) {
791                 kfree(netDevice->ChannelInitEvent);
792
793                 while (!IsListEmpty(&netDevice->ReceivePacketList)) {
794                         entry = REMOVE_HEAD_LIST(&netDevice->ReceivePacketList);
795                         packet = CONTAINING_RECORD(entry,
796                                                    struct hv_netvsc_packet,
797                                                    ListEntry);
798                         kfree(packet);
799                 }
800
801                 ReleaseOutboundNetDevice(Device);
802                 ReleaseInboundNetDevice(Device);
803
804                 FreeNetDevice(netDevice);
805         }
806
807         DPRINT_EXIT(NETVSC);
808         return ret;
809 }
810
811 /**
812  * NetVscOnDeviceRemove - Callback when the root bus device is removed
813  */
814 static int NetVscOnDeviceRemove(struct hv_device *Device)
815 {
816         struct netvsc_device *netDevice;
817         struct hv_netvsc_packet *netvscPacket;
818         LIST_ENTRY *entry;
819
820         DPRINT_ENTER(NETVSC);
821
822         DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...",
823                     Device->Extension);
824
825         /* Stop outbound traffic ie sends and receives completions */
826         netDevice = ReleaseOutboundNetDevice(Device);
827         if (!netDevice) {
828                 DPRINT_ERR(NETVSC, "No net device present!!");
829                 return -1;
830         }
831
832         /* Wait for all send completions */
833         while (atomic_read(&netDevice->NumOutstandingSends)) {
834                 DPRINT_INFO(NETVSC, "waiting for %d requests to complete...",
835                             atomic_read(&netDevice->NumOutstandingSends));
836                 udelay(100);
837         }
838
839         DPRINT_INFO(NETVSC, "Disconnecting from netvsp...");
840
841         NetVscDisconnectFromVsp(netDevice);
842
843         DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...",
844                     Device->Extension);
845
846         /* Stop inbound traffic ie receives and sends completions */
847         netDevice = ReleaseInboundNetDevice(Device);
848
849         /* At this point, no one should be accessing netDevice except in here */
850         DPRINT_INFO(NETVSC, "net device (%p) safe to remove", netDevice);
851
852         /* Now, we can close the channel safely */
853         Device->Driver->VmbusChannelInterface.Close(Device);
854
855         /* Release all resources */
856         while (!IsListEmpty(&netDevice->ReceivePacketList)) {
857                 entry = REMOVE_HEAD_LIST(&netDevice->ReceivePacketList);
858                 netvscPacket = CONTAINING_RECORD(entry,
859                                                  struct hv_netvsc_packet,
860                                                  ListEntry);
861
862                 kfree(netvscPacket);
863         }
864
865         kfree(netDevice->ChannelInitEvent);
866         FreeNetDevice(netDevice);
867
868         DPRINT_EXIT(NETVSC);
869         return 0;
870 }
871
872 /**
873  * NetVscOnCleanup - Perform any cleanup when the driver is removed
874  */
875 static void NetVscOnCleanup(struct hv_driver *drv)
876 {
877         DPRINT_ENTER(NETVSC);
878         DPRINT_EXIT(NETVSC);
879 }
880
881 static void NetVscOnSendCompletion(struct hv_device *Device,
882                                    struct vmpacket_descriptor *Packet)
883 {
884         struct netvsc_device *netDevice;
885         struct nvsp_message *nvspPacket;
886         struct hv_netvsc_packet *nvscPacket;
887
888         DPRINT_ENTER(NETVSC);
889
890         netDevice = GetInboundNetDevice(Device);
891         if (!netDevice) {
892                 DPRINT_ERR(NETVSC, "unable to get net device..."
893                            "device being destroyed?");
894                 DPRINT_EXIT(NETVSC);
895                 return;
896         }
897
898         nvspPacket = (struct nvsp_message *)((unsigned long)Packet + (Packet->DataOffset8 << 3));
899
900         DPRINT_DBG(NETVSC, "send completion packet - type %d",
901                    nvspPacket->Header.MessageType);
902
903         if ((nvspPacket->Header.MessageType == NvspMessageTypeInitComplete) ||
904             (nvspPacket->Header.MessageType ==
905              NvspMessage1TypeSendReceiveBufferComplete) ||
906             (nvspPacket->Header.MessageType ==
907              NvspMessage1TypeSendSendBufferComplete)) {
908                 /* Copy the response back */
909                 memcpy(&netDevice->ChannelInitPacket, nvspPacket,
910                        sizeof(struct nvsp_message));
911                 osd_WaitEventSet(netDevice->ChannelInitEvent);
912         } else if (nvspPacket->Header.MessageType ==
913                    NvspMessage1TypeSendRNDISPacketComplete) {
914                 /* Get the send context */
915                 nvscPacket = (struct hv_netvsc_packet *)(unsigned long)Packet->TransactionId;
916                 ASSERT(nvscPacket);
917
918                 /* Notify the layer above us */
919                 nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext);
920
921                 atomic_dec(&netDevice->NumOutstandingSends);
922         } else {
923                 DPRINT_ERR(NETVSC, "Unknown send completion packet type - "
924                            "%d received!!", nvspPacket->Header.MessageType);
925         }
926
927         PutNetDevice(Device);
928         DPRINT_EXIT(NETVSC);
929 }
930
931 static int NetVscOnSend(struct hv_device *Device,
932                         struct hv_netvsc_packet *Packet)
933 {
934         struct netvsc_device *netDevice;
935         int ret = 0;
936
937         struct nvsp_message sendMessage;
938
939         DPRINT_ENTER(NETVSC);
940
941         netDevice = GetOutboundNetDevice(Device);
942         if (!netDevice) {
943                 DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
944                            "ignoring outbound packets", netDevice);
945                 DPRINT_EXIT(NETVSC);
946                 return -2;
947         }
948
949         sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket;
950         if (Packet->IsDataPacket) {
951                 /* 0 is RMC_DATA; */
952                 sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0;
953         } else {
954                 /* 1 is RMC_CONTROL; */
955                 sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 1;
956         }
957
958         /* Not using send buffer section */
959         sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF;
960         sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0;
961
962         if (Packet->PageBufferCount) {
963                 ret = Device->Driver->VmbusChannelInterface.SendPacketPageBuffer(
964                                         Device, Packet->PageBuffers,
965                                         Packet->PageBufferCount,
966                                         &sendMessage,
967                                         sizeof(struct nvsp_message),
968                                         (unsigned long)Packet);
969         } else {
970                 ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
971                                 &sendMessage,
972                                 sizeof(struct nvsp_message),
973                                 (unsigned long)Packet,
974                                 VmbusPacketTypeDataInBand,
975                                 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
976
977         }
978
979         if (ret != 0)
980                 DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d",
981                            Packet, ret);
982
983         atomic_inc(&netDevice->NumOutstandingSends);
984         PutNetDevice(Device);
985
986         DPRINT_EXIT(NETVSC);
987         return ret;
988 }
989
990 static void NetVscOnReceive(struct hv_device *Device,
991                             struct vmpacket_descriptor *Packet)
992 {
993         struct netvsc_device *netDevice;
994         struct vmtransfer_page_packet_header *vmxferpagePacket;
995         struct nvsp_message *nvspPacket;
996         struct hv_netvsc_packet *netvscPacket = NULL;
997         LIST_ENTRY *entry;
998         unsigned long start;
999         unsigned long end, endVirtual;
1000         /* struct netvsc_driver *netvscDriver; */
1001         struct xferpage_packet *xferpagePacket = NULL;
1002         LIST_ENTRY listHead;
1003         int i, j;
1004         int count = 0, bytesRemain = 0;
1005         unsigned long flags;
1006
1007         DPRINT_ENTER(NETVSC);
1008
1009         netDevice = GetInboundNetDevice(Device);
1010         if (!netDevice) {
1011                 DPRINT_ERR(NETVSC, "unable to get net device..."
1012                            "device being destroyed?");
1013                 DPRINT_EXIT(NETVSC);
1014                 return;
1015         }
1016
1017         /*
1018          * All inbound packets other than send completion should be xfer page
1019          * packet
1020          */
1021         if (Packet->Type != VmbusPacketTypeDataUsingTransferPages) {
1022                 DPRINT_ERR(NETVSC, "Unknown packet type received - %d",
1023                            Packet->Type);
1024                 PutNetDevice(Device);
1025                 return;
1026         }
1027
1028         nvspPacket = (struct nvsp_message *)((unsigned long)Packet +
1029                         (Packet->DataOffset8 << 3));
1030
1031         /* Make sure this is a valid nvsp packet */
1032         if (nvspPacket->Header.MessageType != NvspMessage1TypeSendRNDISPacket) {
1033                 DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d",
1034                            nvspPacket->Header.MessageType);
1035                 PutNetDevice(Device);
1036                 return;
1037         }
1038
1039         DPRINT_DBG(NETVSC, "NVSP packet received - type %d",
1040                    nvspPacket->Header.MessageType);
1041
1042         vmxferpagePacket = (struct vmtransfer_page_packet_header *)Packet;
1043
1044         if (vmxferpagePacket->TransferPageSetId != NETVSC_RECEIVE_BUFFER_ID) {
1045                 DPRINT_ERR(NETVSC, "Invalid xfer page set id - "
1046                            "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID,
1047                            vmxferpagePacket->TransferPageSetId);
1048                 PutNetDevice(Device);
1049                 return;
1050         }
1051
1052         DPRINT_DBG(NETVSC, "xfer page - range count %d",
1053                    vmxferpagePacket->RangeCount);
1054
1055         INITIALIZE_LIST_HEAD(&listHead);
1056
1057         /*
1058          * Grab free packets (range count + 1) to represent this xfer
1059          * page packet. +1 to represent the xfer page packet itself.
1060          * We grab it here so that we know exactly how many we can
1061          * fulfil
1062          */
1063         spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
1064         while (!IsListEmpty(&netDevice->ReceivePacketList)) {
1065                 entry = REMOVE_HEAD_LIST(&netDevice->ReceivePacketList);
1066                 netvscPacket = CONTAINING_RECORD(entry,
1067                                                  struct hv_netvsc_packet,
1068                                                  ListEntry);
1069
1070                 INSERT_TAIL_LIST(&listHead, &netvscPacket->ListEntry);
1071
1072                 if (++count == vmxferpagePacket->RangeCount + 1)
1073                         break;
1074         }
1075         spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags);
1076
1077         /*
1078          * We need at least 2 netvsc pkts (1 to represent the xfer
1079          * page and at least 1 for the range) i.e. we can handled
1080          * some of the xfer page packet ranges...
1081          */
1082         if (count < 2) {
1083                 DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. "
1084                            "Dropping this xfer page packet completely!",
1085                            count, vmxferpagePacket->RangeCount + 1);
1086
1087                 /* Return it to the freelist */
1088                 spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
1089                 for (i = count; i != 0; i--) {
1090                         entry = REMOVE_HEAD_LIST(&listHead);
1091                         netvscPacket = CONTAINING_RECORD(entry,
1092                                                 struct hv_netvsc_packet,
1093                                                 ListEntry);
1094
1095                         INSERT_TAIL_LIST(&netDevice->ReceivePacketList,
1096                                          &netvscPacket->ListEntry);
1097                 }
1098                 spin_unlock_irqrestore(&netDevice->receive_packet_list_lock,
1099                                        flags);
1100
1101                 NetVscSendReceiveCompletion(Device,
1102                                             vmxferpagePacket->d.TransactionId);
1103
1104                 PutNetDevice(Device);
1105                 return;
1106         }
1107
1108         /* Remove the 1st packet to represent the xfer page packet itself */
1109         entry = REMOVE_HEAD_LIST(&listHead);
1110         xferpagePacket = CONTAINING_RECORD(entry, struct xferpage_packet,
1111                                            ListEntry);
1112         /* This is how much we can satisfy */
1113         xferpagePacket->Count = count - 1;
1114         ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <=
1115                 vmxferpagePacket->RangeCount);
1116
1117         if (xferpagePacket->Count != vmxferpagePacket->RangeCount) {
1118                 DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer "
1119                             "page...got %d", vmxferpagePacket->RangeCount,
1120                             xferpagePacket->Count);
1121         }
1122
1123         /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
1124         for (i = 0; i < (count - 1); i++) {
1125                 entry = REMOVE_HEAD_LIST(&listHead);
1126                 netvscPacket = CONTAINING_RECORD(entry,
1127                                                  struct hv_netvsc_packet,
1128                                                  ListEntry);
1129
1130                 /* Initialize the netvsc packet */
1131                 netvscPacket->XferPagePacket = xferpagePacket;
1132                 netvscPacket->Completion.Recv.OnReceiveCompletion =
1133                                         NetVscOnReceiveCompletion;
1134                 netvscPacket->Completion.Recv.ReceiveCompletionContext =
1135                                         netvscPacket;
1136                 netvscPacket->Device = Device;
1137                 /* Save this so that we can send it back */
1138                 netvscPacket->Completion.Recv.ReceiveCompletionTid =
1139                                         vmxferpagePacket->d.TransactionId;
1140
1141                 netvscPacket->TotalDataBufferLength =
1142                                         vmxferpagePacket->Ranges[i].ByteCount;
1143                 netvscPacket->PageBufferCount = 1;
1144
1145                 ASSERT(vmxferpagePacket->Ranges[i].ByteOffset +
1146                         vmxferpagePacket->Ranges[i].ByteCount <
1147                         netDevice->ReceiveBufferSize);
1148
1149                 netvscPacket->PageBuffers[0].Length =
1150                                         vmxferpagePacket->Ranges[i].ByteCount;
1151
1152                 start = virt_to_phys((void *)((unsigned long)netDevice->ReceiveBuffer + vmxferpagePacket->Ranges[i].ByteOffset));
1153
1154                 netvscPacket->PageBuffers[0].Pfn = start >> PAGE_SHIFT;
1155                 endVirtual = (unsigned long)netDevice->ReceiveBuffer
1156                     + vmxferpagePacket->Ranges[i].ByteOffset
1157                     + vmxferpagePacket->Ranges[i].ByteCount - 1;
1158                 end = virt_to_phys((void *)endVirtual);
1159
1160                 /* Calculate the page relative offset */
1161                 netvscPacket->PageBuffers[0].Offset =
1162                         vmxferpagePacket->Ranges[i].ByteOffset & (PAGE_SIZE - 1);
1163                 if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) {
1164                         /* Handle frame across multiple pages: */
1165                         netvscPacket->PageBuffers[0].Length =
1166                                 (netvscPacket->PageBuffers[0].Pfn << PAGE_SHIFT)
1167                                 + PAGE_SIZE - start;
1168                         bytesRemain = netvscPacket->TotalDataBufferLength -
1169                                         netvscPacket->PageBuffers[0].Length;
1170                         for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) {
1171                                 netvscPacket->PageBuffers[j].Offset = 0;
1172                                 if (bytesRemain <= PAGE_SIZE) {
1173                                         netvscPacket->PageBuffers[j].Length = bytesRemain;
1174                                         bytesRemain = 0;
1175                                 } else {
1176                                         netvscPacket->PageBuffers[j].Length = PAGE_SIZE;
1177                                         bytesRemain -= PAGE_SIZE;
1178                                 }
1179                                 netvscPacket->PageBuffers[j].Pfn =
1180                                     virt_to_phys((void *)(endVirtual - bytesRemain)) >> PAGE_SHIFT;
1181                                 netvscPacket->PageBufferCount++;
1182                                 if (bytesRemain == 0)
1183                                         break;
1184                         }
1185                         ASSERT(bytesRemain == 0);
1186                 }
1187                 DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => "
1188                            "(pfn %llx, offset %u, len %u)", i,
1189                            vmxferpagePacket->Ranges[i].ByteOffset,
1190                            vmxferpagePacket->Ranges[i].ByteCount,
1191                            netvscPacket->PageBuffers[0].Pfn,
1192                            netvscPacket->PageBuffers[0].Offset,
1193                            netvscPacket->PageBuffers[0].Length);
1194
1195                 /* Pass it to the upper layer */
1196                 ((struct netvsc_driver *)Device->Driver)->OnReceiveCallback(Device, netvscPacket);
1197
1198                 NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext);
1199         }
1200
1201         ASSERT(IsListEmpty(&listHead));
1202
1203         PutNetDevice(Device);
1204         DPRINT_EXIT(NETVSC);
1205 }
1206
1207 static void NetVscSendReceiveCompletion(struct hv_device *Device,
1208                                         u64 TransactionId)
1209 {
1210         struct nvsp_message recvcompMessage;
1211         int retries = 0;
1212         int ret;
1213
1214         DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx",
1215                    TransactionId);
1216
1217         recvcompMessage.Header.MessageType =
1218                                 NvspMessage1TypeSendRNDISPacketComplete;
1219
1220         /* FIXME: Pass in the status */
1221         recvcompMessage.Messages.Version1Messages.SendRNDISPacketComplete.Status = NvspStatusSuccess;
1222
1223 retry_send_cmplt:
1224         /* Send the completion */
1225         ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
1226                                         &recvcompMessage,
1227                                         sizeof(struct nvsp_message),
1228                                         TransactionId,
1229                                         VmbusPacketTypeCompletion, 0);
1230         if (ret == 0) {
1231                 /* success */
1232                 /* no-op */
1233         } else if (ret == -1) {
1234                 /* no more room...wait a bit and attempt to retry 3 times */
1235                 retries++;
1236                 DPRINT_ERR(NETVSC, "unable to send receive completion pkt "
1237                            "(tid %llx)...retrying %d", TransactionId, retries);
1238
1239                 if (retries < 4) {
1240                         udelay(100);
1241                         goto retry_send_cmplt;
1242                 } else {
1243                         DPRINT_ERR(NETVSC, "unable to send receive completion "
1244                                   "pkt (tid %llx)...give up retrying",
1245                                   TransactionId);
1246                 }
1247         } else {
1248                 DPRINT_ERR(NETVSC, "unable to send receive completion pkt - "
1249                            "%llx", TransactionId);
1250         }
1251 }
1252
1253 /* Send a receive completion packet to RNDIS device (ie NetVsp) */
1254 static void NetVscOnReceiveCompletion(void *Context)
1255 {
1256         struct hv_netvsc_packet *packet = Context;
1257         struct hv_device *device = (struct hv_device *)packet->Device;
1258         struct netvsc_device *netDevice;
1259         u64 transactionId = 0;
1260         bool fSendReceiveComp = false;
1261         unsigned long flags;
1262
1263         DPRINT_ENTER(NETVSC);
1264
1265         ASSERT(packet->XferPagePacket);
1266
1267         /*
1268          * Even though it seems logical to do a GetOutboundNetDevice() here to
1269          * send out receive completion, we are using GetInboundNetDevice()
1270          * since we may have disable outbound traffic already.
1271          */
1272         netDevice = GetInboundNetDevice(device);
1273         if (!netDevice) {
1274                 DPRINT_ERR(NETVSC, "unable to get net device..."
1275                            "device being destroyed?");
1276                 DPRINT_EXIT(NETVSC);
1277                 return;
1278         }
1279
1280         /* Overloading use of the lock. */
1281         spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
1282
1283         ASSERT(packet->XferPagePacket->Count > 0);
1284         packet->XferPagePacket->Count--;
1285
1286         /*
1287          * Last one in the line that represent 1 xfer page packet.
1288          * Return the xfer page packet itself to the freelist
1289          */
1290         if (packet->XferPagePacket->Count == 0) {
1291                 fSendReceiveComp = true;
1292                 transactionId = packet->Completion.Recv.ReceiveCompletionTid;
1293
1294                 INSERT_TAIL_LIST(&netDevice->ReceivePacketList,
1295                                  &packet->XferPagePacket->ListEntry);
1296         }
1297
1298         /* Put the packet back */
1299         INSERT_TAIL_LIST(&netDevice->ReceivePacketList, &packet->ListEntry);
1300         spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags);
1301
1302         /* Send a receive completion for the xfer page packet */
1303         if (fSendReceiveComp)
1304                 NetVscSendReceiveCompletion(device, transactionId);
1305
1306         PutNetDevice(device);
1307         DPRINT_EXIT(NETVSC);
1308 }
1309
1310 void NetVscOnChannelCallback(void *Context)
1311 {
1312         const int netPacketSize = 2048;
1313         int ret;
1314         struct hv_device *device = Context;
1315         struct netvsc_device *netDevice;
1316         u32 bytesRecvd;
1317         u64 requestId;
1318         unsigned char packet[netPacketSize];
1319         struct vmpacket_descriptor *desc;
1320         unsigned char *buffer = packet;
1321         int bufferlen = netPacketSize;
1322
1323
1324         DPRINT_ENTER(NETVSC);
1325
1326         ASSERT(device);
1327
1328         netDevice = GetInboundNetDevice(device);
1329         if (!netDevice) {
1330                 DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
1331                            "ignoring inbound packets", netDevice);
1332                 DPRINT_EXIT(NETVSC);
1333                 return;
1334         }
1335
1336         do {
1337                 ret = device->Driver->VmbusChannelInterface.RecvPacketRaw(
1338                                                 device, buffer, bufferlen,
1339                                                 &bytesRecvd, &requestId);
1340                 if (ret == 0) {
1341                         if (bytesRecvd > 0) {
1342                                 DPRINT_DBG(NETVSC, "receive %d bytes, tid %llx",
1343                                            bytesRecvd, requestId);
1344
1345                                 desc = (struct vmpacket_descriptor *)buffer;
1346                                 switch (desc->Type) {
1347                                 case VmbusPacketTypeCompletion:
1348                                         NetVscOnSendCompletion(device, desc);
1349                                         break;
1350
1351                                 case VmbusPacketTypeDataUsingTransferPages:
1352                                         NetVscOnReceive(device, desc);
1353                                         break;
1354
1355                                 default:
1356                                         DPRINT_ERR(NETVSC,
1357                                                    "unhandled packet type %d, "
1358                                                    "tid %llx len %d\n",
1359                                                    desc->Type, requestId,
1360                                                    bytesRecvd);
1361                                         break;
1362                                 }
1363
1364                                 /* reset */
1365                                 if (bufferlen > netPacketSize) {
1366                                         kfree(buffer);
1367                                         buffer = packet;
1368                                         bufferlen = netPacketSize;
1369                                 }
1370                         } else {
1371                                 /* reset */
1372                                 if (bufferlen > netPacketSize) {
1373                                         kfree(buffer);
1374                                         buffer = packet;
1375                                         bufferlen = netPacketSize;
1376                                 }
1377
1378                                 break;
1379                         }
1380                 } else if (ret == -2) {
1381                         /* Handle large packet */
1382                         buffer = kmalloc(bytesRecvd, GFP_ATOMIC);
1383                         if (buffer == NULL) {
1384                                 /* Try again next time around */
1385                                 DPRINT_ERR(NETVSC,
1386                                            "unable to allocate buffer of size "
1387                                            "(%d)!!", bytesRecvd);
1388                                 break;
1389                         }
1390
1391                         bufferlen = bytesRecvd;
1392                 } else {
1393                         ASSERT(0);
1394                 }
1395         } while (1);
1396
1397         PutNetDevice(device);
1398         DPRINT_EXIT(NETVSC);
1399         return;
1400 }