1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/kernel.h>
22#include <linux/highmem.h>
23#include <linux/io.h>
24#include "osd.h"
25#include "logging.h"
26#include "NetVscApi.h"
27#include "RndisFilter.h"
28
29
30struct rndis_filter_driver_object {
31
32 struct netvsc_driver InnerDriver;
33};
34
35enum rndis_device_state {
36 RNDIS_DEV_UNINITIALIZED = 0,
37 RNDIS_DEV_INITIALIZING,
38 RNDIS_DEV_INITIALIZED,
39 RNDIS_DEV_DATAINITIALIZED,
40};
41
42struct rndis_device {
43 struct netvsc_device *NetDevice;
44
45 enum rndis_device_state State;
46 u32 LinkStatus;
47 atomic_t NewRequestId;
48
49 spinlock_t request_lock;
50 struct list_head RequestList;
51
52 unsigned char HwMacAddr[HW_MACADDR_LEN];
53};
54
55struct rndis_request {
56 struct list_head ListEntry;
57 struct osd_waitevent *WaitEvent;
58
59
60
61
62
63
64 struct rndis_message ResponseMessage;
65
66
67 struct hv_netvsc_packet Packet;
68 struct hv_page_buffer Buffer;
69
70 struct rndis_message RequestMessage;
71};
72
73
74struct rndis_filter_packet {
75 void *CompletionContext;
76 void (*OnCompletion)(void *context);
77 struct rndis_message Message;
78};
79
80
81static int RndisFilterOnDeviceAdd(struct hv_device *Device,
82 void *AdditionalInfo);
83
84static int RndisFilterOnDeviceRemove(struct hv_device *Device);
85
86static void RndisFilterOnCleanup(struct hv_driver *Driver);
87
88static int RndisFilterOnOpen(struct hv_device *Device);
89
90static int RndisFilterOnClose(struct hv_device *Device);
91
92static int RndisFilterOnSend(struct hv_device *Device,
93 struct hv_netvsc_packet *Packet);
94
95static void RndisFilterOnSendCompletion(void *Context);
96
97static void RndisFilterOnSendRequestCompletion(void *Context);
98
99
100
101static struct rndis_filter_driver_object gRndisFilter;
102
103static struct rndis_device *GetRndisDevice(void)
104{
105 struct rndis_device *device;
106
107 device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
108 if (!device)
109 return NULL;
110
111 spin_lock_init(&device->request_lock);
112
113 INIT_LIST_HEAD(&device->RequestList);
114
115 device->State = RNDIS_DEV_UNINITIALIZED;
116
117 return device;
118}
119
120static struct rndis_request *GetRndisRequest(struct rndis_device *Device,
121 u32 MessageType,
122 u32 MessageLength)
123{
124 struct rndis_request *request;
125 struct rndis_message *rndisMessage;
126 struct rndis_set_request *set;
127 unsigned long flags;
128
129 request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
130 if (!request)
131 return NULL;
132
133 request->WaitEvent = osd_WaitEventCreate();
134 if (!request->WaitEvent) {
135 kfree(request);
136 return NULL;
137 }
138
139 rndisMessage = &request->RequestMessage;
140 rndisMessage->NdisMessageType = MessageType;
141 rndisMessage->MessageLength = MessageLength;
142
143
144
145
146
147
148 set = &rndisMessage->Message.SetRequest;
149 set->RequestId = atomic_inc_return(&Device->NewRequestId);
150
151
152 spin_lock_irqsave(&Device->request_lock, flags);
153 list_add_tail(&request->ListEntry, &Device->RequestList);
154 spin_unlock_irqrestore(&Device->request_lock, flags);
155
156 return request;
157}
158
159static void PutRndisRequest(struct rndis_device *Device,
160 struct rndis_request *Request)
161{
162 unsigned long flags;
163
164 spin_lock_irqsave(&Device->request_lock, flags);
165 list_del(&Request->ListEntry);
166 spin_unlock_irqrestore(&Device->request_lock, flags);
167
168 kfree(Request->WaitEvent);
169 kfree(Request);
170}
171
172static void DumpRndisMessage(struct rndis_message *RndisMessage)
173{
174 switch (RndisMessage->NdisMessageType) {
175 case REMOTE_NDIS_PACKET_MSG:
176 DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, "
177 "data offset %u data len %u, # oob %u, "
178 "oob offset %u, oob len %u, pkt offset %u, "
179 "pkt len %u",
180 RndisMessage->MessageLength,
181 RndisMessage->Message.Packet.DataOffset,
182 RndisMessage->Message.Packet.DataLength,
183 RndisMessage->Message.Packet.NumOOBDataElements,
184 RndisMessage->Message.Packet.OOBDataOffset,
185 RndisMessage->Message.Packet.OOBDataLength,
186 RndisMessage->Message.Packet.PerPacketInfoOffset,
187 RndisMessage->Message.Packet.PerPacketInfoLength);
188 break;
189
190 case REMOTE_NDIS_INITIALIZE_CMPLT:
191 DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT "
192 "(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
193 "device flags %d, max xfer size 0x%x, max pkts %u, "
194 "pkt aligned %u)",
195 RndisMessage->MessageLength,
196 RndisMessage->Message.InitializeComplete.RequestId,
197 RndisMessage->Message.InitializeComplete.Status,
198 RndisMessage->Message.InitializeComplete.MajorVersion,
199 RndisMessage->Message.InitializeComplete.MinorVersion,
200 RndisMessage->Message.InitializeComplete.DeviceFlags,
201 RndisMessage->Message.InitializeComplete.MaxTransferSize,
202 RndisMessage->Message.InitializeComplete.MaxPacketsPerMessage,
203 RndisMessage->Message.InitializeComplete.PacketAlignmentFactor);
204 break;
205
206 case REMOTE_NDIS_QUERY_CMPLT:
207 DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT "
208 "(len %u, id 0x%x, status 0x%x, buf len %u, "
209 "buf offset %u)",
210 RndisMessage->MessageLength,
211 RndisMessage->Message.QueryComplete.RequestId,
212 RndisMessage->Message.QueryComplete.Status,
213 RndisMessage->Message.QueryComplete.InformationBufferLength,
214 RndisMessage->Message.QueryComplete.InformationBufferOffset);
215 break;
216
217 case REMOTE_NDIS_SET_CMPLT:
218 DPRINT_DBG(NETVSC,
219 "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)",
220 RndisMessage->MessageLength,
221 RndisMessage->Message.SetComplete.RequestId,
222 RndisMessage->Message.SetComplete.Status);
223 break;
224
225 case REMOTE_NDIS_INDICATE_STATUS_MSG:
226 DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG "
227 "(len %u, status 0x%x, buf len %u, buf offset %u)",
228 RndisMessage->MessageLength,
229 RndisMessage->Message.IndicateStatus.Status,
230 RndisMessage->Message.IndicateStatus.StatusBufferLength,
231 RndisMessage->Message.IndicateStatus.StatusBufferOffset);
232 break;
233
234 default:
235 DPRINT_DBG(NETVSC, "0x%x (len %u)",
236 RndisMessage->NdisMessageType,
237 RndisMessage->MessageLength);
238 break;
239 }
240}
241
242static int RndisFilterSendRequest(struct rndis_device *Device,
243 struct rndis_request *Request)
244{
245 int ret;
246 struct hv_netvsc_packet *packet;
247
248 DPRINT_ENTER(NETVSC);
249
250
251 packet = &Request->Packet;
252
253 packet->IsDataPacket = false;
254 packet->TotalDataBufferLength = Request->RequestMessage.MessageLength;
255 packet->PageBufferCount = 1;
256
257 packet->PageBuffers[0].Pfn = virt_to_phys(&Request->RequestMessage) >>
258 PAGE_SHIFT;
259 packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength;
260 packet->PageBuffers[0].Offset =
261 (unsigned long)&Request->RequestMessage & (PAGE_SIZE - 1);
262
263 packet->Completion.Send.SendCompletionContext = Request;
264 packet->Completion.Send.OnSendCompletion =
265 RndisFilterOnSendRequestCompletion;
266 packet->Completion.Send.SendCompletionTid = (unsigned long)Device;
267
268 ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet);
269 DPRINT_EXIT(NETVSC);
270 return ret;
271}
272
273static void RndisFilterReceiveResponse(struct rndis_device *Device,
274 struct rndis_message *Response)
275{
276 struct rndis_request *request = NULL;
277 bool found = false;
278 unsigned long flags;
279
280 DPRINT_ENTER(NETVSC);
281
282 spin_lock_irqsave(&Device->request_lock, flags);
283 list_for_each_entry(request, &Device->RequestList, ListEntry) {
284
285
286
287
288 if (request->RequestMessage.Message.InitializeRequest.RequestId
289 == Response->Message.InitializeComplete.RequestId) {
290 DPRINT_DBG(NETVSC, "found rndis request for "
291 "this response (id 0x%x req type 0x%x res "
292 "type 0x%x)",
293 request->RequestMessage.Message.InitializeRequest.RequestId,
294 request->RequestMessage.NdisMessageType,
295 Response->NdisMessageType);
296
297 found = true;
298 break;
299 }
300 }
301 spin_unlock_irqrestore(&Device->request_lock, flags);
302
303 if (found) {
304 if (Response->MessageLength <= sizeof(struct rndis_message)) {
305 memcpy(&request->ResponseMessage, Response,
306 Response->MessageLength);
307 } else {
308 DPRINT_ERR(NETVSC, "rndis response buffer overflow "
309 "detected (size %u max %zu)",
310 Response->MessageLength,
311 sizeof(struct rndis_filter_packet));
312
313 if (Response->NdisMessageType ==
314 REMOTE_NDIS_RESET_CMPLT) {
315
316 request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW;
317 } else {
318 request->ResponseMessage.Message.InitializeComplete.Status = STATUS_BUFFER_OVERFLOW;
319 }
320 }
321
322 osd_WaitEventSet(request->WaitEvent);
323 } else {
324 DPRINT_ERR(NETVSC, "no rndis request found for this response "
325 "(id 0x%x res type 0x%x)",
326 Response->Message.InitializeComplete.RequestId,
327 Response->NdisMessageType);
328 }
329
330 DPRINT_EXIT(NETVSC);
331}
332
333static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device,
334 struct rndis_message *Response)
335{
336 struct rndis_indicate_status *indicate =
337 &Response->Message.IndicateStatus;
338
339 if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) {
340 gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 1);
341 } else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) {
342 gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 0);
343 } else {
344
345
346
347 }
348}
349
350static void RndisFilterReceiveData(struct rndis_device *Device,
351 struct rndis_message *Message,
352 struct hv_netvsc_packet *Packet)
353{
354 struct rndis_packet *rndisPacket;
355 u32 dataOffset;
356
357 DPRINT_ENTER(NETVSC);
358
359
360 ASSERT(Packet->PageBuffers[0].Length >
361 RNDIS_MESSAGE_SIZE(struct rndis_packet));
362
363 rndisPacket = &Message->Message.Packet;
364
365
366
367
368
369
370
371 dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset;
372
373 Packet->TotalDataBufferLength -= dataOffset;
374 Packet->PageBuffers[0].Offset += dataOffset;
375 Packet->PageBuffers[0].Length -= dataOffset;
376
377 Packet->IsDataPacket = true;
378
379 gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device,
380 Packet);
381
382 DPRINT_EXIT(NETVSC);
383}
384
385static int RndisFilterOnReceive(struct hv_device *Device,
386 struct hv_netvsc_packet *Packet)
387{
388 struct netvsc_device *netDevice = Device->Extension;
389 struct rndis_device *rndisDevice;
390 struct rndis_message rndisMessage;
391 struct rndis_message *rndisHeader;
392
393 DPRINT_ENTER(NETVSC);
394
395 ASSERT(netDevice);
396
397 if (!netDevice->Extension) {
398 DPRINT_ERR(NETVSC, "got rndis message but no rndis device..."
399 "dropping this message!");
400 DPRINT_EXIT(NETVSC);
401 return -1;
402 }
403
404 rndisDevice = (struct rndis_device *)netDevice->Extension;
405 if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED) {
406 DPRINT_ERR(NETVSC, "got rndis message but rndis device "
407 "uninitialized...dropping this message!");
408 DPRINT_EXIT(NETVSC);
409 return -1;
410 }
411
412 rndisHeader = (struct rndis_message *)kmap_atomic(
413 pfn_to_page(Packet->PageBuffers[0].Pfn), KM_IRQ0);
414
415 rndisHeader = (void *)((unsigned long)rndisHeader +
416 Packet->PageBuffers[0].Offset);
417
418
419
420
421
422
423
424#if 0
425 if (Packet->TotalDataBufferLength != rndisHeader->MessageLength) {
426 kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset,
427 KM_IRQ0);
428
429 DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u "
430 "bytes got %u)...dropping this message!",
431 rndisHeader->MessageLength,
432 Packet->TotalDataBufferLength);
433 DPRINT_EXIT(NETVSC);
434 return -1;
435 }
436#endif
437
438 if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) &&
439 (rndisHeader->MessageLength > sizeof(struct rndis_message))) {
440 DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow "
441 "detected (got %u, max %zu)...marking it an error!",
442 rndisHeader->MessageLength,
443 sizeof(struct rndis_message));
444 }
445
446 memcpy(&rndisMessage, rndisHeader,
447 (rndisHeader->MessageLength > sizeof(struct rndis_message)) ?
448 sizeof(struct rndis_message) :
449 rndisHeader->MessageLength);
450
451 kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, KM_IRQ0);
452
453 DumpRndisMessage(&rndisMessage);
454
455 switch (rndisMessage.NdisMessageType) {
456 case REMOTE_NDIS_PACKET_MSG:
457
458 RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet);
459 break;
460
461 case REMOTE_NDIS_INITIALIZE_CMPLT:
462 case REMOTE_NDIS_QUERY_CMPLT:
463 case REMOTE_NDIS_SET_CMPLT:
464
465
466
467 RndisFilterReceiveResponse(rndisDevice, &rndisMessage);
468 break;
469
470 case REMOTE_NDIS_INDICATE_STATUS_MSG:
471
472 RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage);
473 break;
474 default:
475 DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)",
476 rndisMessage.NdisMessageType,
477 rndisMessage.MessageLength);
478 break;
479 }
480
481 DPRINT_EXIT(NETVSC);
482 return 0;
483}
484
485static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid,
486 void *Result, u32 *ResultSize)
487{
488 struct rndis_request *request;
489 u32 inresultSize = *ResultSize;
490 struct rndis_query_request *query;
491 struct rndis_query_complete *queryComplete;
492 int ret = 0;
493
494 DPRINT_ENTER(NETVSC);
495
496 ASSERT(Result);
497
498 *ResultSize = 0;
499 request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG,
500 RNDIS_MESSAGE_SIZE(struct rndis_query_request));
501 if (!request) {
502 ret = -1;
503 goto Cleanup;
504 }
505
506
507 query = &request->RequestMessage.Message.QueryRequest;
508 query->Oid = Oid;
509 query->InformationBufferOffset = sizeof(struct rndis_query_request);
510 query->InformationBufferLength = 0;
511 query->DeviceVcHandle = 0;
512
513 ret = RndisFilterSendRequest(Device, request);
514 if (ret != 0)
515 goto Cleanup;
516
517 osd_WaitEventWait(request->WaitEvent);
518
519
520 queryComplete = &request->ResponseMessage.Message.QueryComplete;
521
522 if (queryComplete->InformationBufferLength > inresultSize) {
523 ret = -1;
524 goto Cleanup;
525 }
526
527 memcpy(Result,
528 (void *)((unsigned long)queryComplete +
529 queryComplete->InformationBufferOffset),
530 queryComplete->InformationBufferLength);
531
532 *ResultSize = queryComplete->InformationBufferLength;
533
534Cleanup:
535 if (request)
536 PutRndisRequest(Device, request);
537 DPRINT_EXIT(NETVSC);
538
539 return ret;
540}
541
542static int RndisFilterQueryDeviceMac(struct rndis_device *Device)
543{
544 u32 size = HW_MACADDR_LEN;
545
546 return RndisFilterQueryDevice(Device,
547 RNDIS_OID_802_3_PERMANENT_ADDRESS,
548 Device->HwMacAddr, &size);
549}
550
551static int RndisFilterQueryDeviceLinkStatus(struct rndis_device *Device)
552{
553 u32 size = sizeof(u32);
554
555 return RndisFilterQueryDevice(Device,
556 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
557 &Device->LinkStatus, &size);
558}
559
560static int RndisFilterSetPacketFilter(struct rndis_device *Device,
561 u32 NewFilter)
562{
563 struct rndis_request *request;
564 struct rndis_set_request *set;
565 struct rndis_set_complete *setComplete;
566 u32 status;
567 int ret;
568
569 DPRINT_ENTER(NETVSC);
570
571 ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <=
572 sizeof(struct rndis_message));
573
574 request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG,
575 RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
576 sizeof(u32));
577 if (!request) {
578 ret = -1;
579 goto Cleanup;
580 }
581
582
583 set = &request->RequestMessage.Message.SetRequest;
584 set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
585 set->InformationBufferLength = sizeof(u32);
586 set->InformationBufferOffset = sizeof(struct rndis_set_request);
587
588 memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
589 &NewFilter, sizeof(u32));
590
591 ret = RndisFilterSendRequest(Device, request);
592 if (ret != 0)
593 goto Cleanup;
594
595 ret = osd_WaitEventWaitEx(request->WaitEvent, 2000);
596 if (!ret) {
597 ret = -1;
598 DPRINT_ERR(NETVSC, "timeout before we got a set response...");
599
600
601
602
603 goto Exit;
604 } else {
605 if (ret > 0)
606 ret = 0;
607 setComplete = &request->ResponseMessage.Message.SetComplete;
608 status = setComplete->Status;
609 }
610
611Cleanup:
612 if (request)
613 PutRndisRequest(Device, request);
614Exit:
615 DPRINT_EXIT(NETVSC);
616
617 return ret;
618}
619
620int RndisFilterInit(struct netvsc_driver *Driver)
621{
622 DPRINT_ENTER(NETVSC);
623
624 DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd",
625 sizeof(struct rndis_filter_packet));
626
627 Driver->RequestExtSize = sizeof(struct rndis_filter_packet);
628 Driver->AdditionalRequestPageBufferCount = 1;
629
630
631
632 memset(&gRndisFilter, 0, sizeof(struct rndis_filter_driver_object));
633
634
635
636
637
638
639
640 gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd;
641 gRndisFilter.InnerDriver.Base.OnDeviceRemove =
642 Driver->Base.OnDeviceRemove;
643 gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup;
644
645 ASSERT(Driver->OnSend);
646 ASSERT(Driver->OnReceiveCallback);
647 gRndisFilter.InnerDriver.OnSend = Driver->OnSend;
648 gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback;
649 gRndisFilter.InnerDriver.OnLinkStatusChanged =
650 Driver->OnLinkStatusChanged;
651
652
653 Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd;
654 Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove;
655 Driver->Base.OnCleanup = RndisFilterOnCleanup;
656 Driver->OnSend = RndisFilterOnSend;
657 Driver->OnOpen = RndisFilterOnOpen;
658 Driver->OnClose = RndisFilterOnClose;
659
660 Driver->OnReceiveCallback = RndisFilterOnReceive;
661
662 DPRINT_EXIT(NETVSC);
663
664 return 0;
665}
666
667static int RndisFilterInitDevice(struct rndis_device *Device)
668{
669 struct rndis_request *request;
670 struct rndis_initialize_request *init;
671 struct rndis_initialize_complete *initComplete;
672 u32 status;
673 int ret;
674
675 DPRINT_ENTER(NETVSC);
676
677 request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG,
678 RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
679 if (!request) {
680 ret = -1;
681 goto Cleanup;
682 }
683
684
685 init = &request->RequestMessage.Message.InitializeRequest;
686 init->MajorVersion = RNDIS_MAJOR_VERSION;
687 init->MinorVersion = RNDIS_MINOR_VERSION;
688
689 init->MaxTransferSize = 2048;
690
691 Device->State = RNDIS_DEV_INITIALIZING;
692
693 ret = RndisFilterSendRequest(Device, request);
694 if (ret != 0) {
695 Device->State = RNDIS_DEV_UNINITIALIZED;
696 goto Cleanup;
697 }
698
699 osd_WaitEventWait(request->WaitEvent);
700
701 initComplete = &request->ResponseMessage.Message.InitializeComplete;
702 status = initComplete->Status;
703 if (status == RNDIS_STATUS_SUCCESS) {
704 Device->State = RNDIS_DEV_INITIALIZED;
705 ret = 0;
706 } else {
707 Device->State = RNDIS_DEV_UNINITIALIZED;
708 ret = -1;
709 }
710
711Cleanup:
712 if (request)
713 PutRndisRequest(Device, request);
714 DPRINT_EXIT(NETVSC);
715
716 return ret;
717}
718
719static void RndisFilterHaltDevice(struct rndis_device *Device)
720{
721 struct rndis_request *request;
722 struct rndis_halt_request *halt;
723
724 DPRINT_ENTER(NETVSC);
725
726
727 request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG,
728 RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
729 if (!request)
730 goto Cleanup;
731
732
733 halt = &request->RequestMessage.Message.HaltRequest;
734 halt->RequestId = atomic_inc_return(&Device->NewRequestId);
735
736
737 RndisFilterSendRequest(Device, request);
738
739 Device->State = RNDIS_DEV_UNINITIALIZED;
740
741Cleanup:
742 if (request)
743 PutRndisRequest(Device, request);
744 DPRINT_EXIT(NETVSC);
745 return;
746}
747
748static int RndisFilterOpenDevice(struct rndis_device *Device)
749{
750 int ret;
751
752 DPRINT_ENTER(NETVSC);
753
754 if (Device->State != RNDIS_DEV_INITIALIZED)
755 return 0;
756
757 ret = RndisFilterSetPacketFilter(Device,
758 NDIS_PACKET_TYPE_BROADCAST |
759 NDIS_PACKET_TYPE_DIRECTED);
760 if (ret == 0)
761 Device->State = RNDIS_DEV_DATAINITIALIZED;
762
763 DPRINT_EXIT(NETVSC);
764 return ret;
765}
766
767static int RndisFilterCloseDevice(struct rndis_device *Device)
768{
769 int ret;
770
771 DPRINT_ENTER(NETVSC);
772
773 if (Device->State != RNDIS_DEV_DATAINITIALIZED)
774 return 0;
775
776 ret = RndisFilterSetPacketFilter(Device, 0);
777 if (ret == 0)
778 Device->State = RNDIS_DEV_INITIALIZED;
779
780 DPRINT_EXIT(NETVSC);
781
782 return ret;
783}
784
785static int RndisFilterOnDeviceAdd(struct hv_device *Device,
786 void *AdditionalInfo)
787{
788 int ret;
789 struct netvsc_device *netDevice;
790 struct rndis_device *rndisDevice;
791 struct netvsc_device_info *deviceInfo = AdditionalInfo;
792
793 DPRINT_ENTER(NETVSC);
794
795 rndisDevice = GetRndisDevice();
796 if (!rndisDevice) {
797 DPRINT_EXIT(NETVSC);
798 return -1;
799 }
800
801 DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);
802
803
804
805
806
807
808 ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo);
809 if (ret != 0) {
810 kfree(rndisDevice);
811 DPRINT_EXIT(NETVSC);
812 return ret;
813 }
814
815
816
817 netDevice = Device->Extension;
818 ASSERT(netDevice);
819 ASSERT(netDevice->Device);
820
821 netDevice->Extension = rndisDevice;
822 rndisDevice->NetDevice = netDevice;
823
824
825 ret = RndisFilterInitDevice(rndisDevice);
826 if (ret != 0) {
827
828
829
830
831 }
832
833
834 ret = RndisFilterQueryDeviceMac(rndisDevice);
835 if (ret != 0) {
836
837
838
839 }
840
841 DPRINT_INFO(NETVSC, "Device 0x%p mac addr %02x%02x%02x%02x%02x%02x",
842 rndisDevice,
843 rndisDevice->HwMacAddr[0],
844 rndisDevice->HwMacAddr[1],
845 rndisDevice->HwMacAddr[2],
846 rndisDevice->HwMacAddr[3],
847 rndisDevice->HwMacAddr[4],
848 rndisDevice->HwMacAddr[5]);
849
850 memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, HW_MACADDR_LEN);
851
852 RndisFilterQueryDeviceLinkStatus(rndisDevice);
853
854 deviceInfo->LinkState = rndisDevice->LinkStatus;
855 DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice,
856 ((deviceInfo->LinkState) ? ("down") : ("up")));
857
858 DPRINT_EXIT(NETVSC);
859
860 return ret;
861}
862
863static int RndisFilterOnDeviceRemove(struct hv_device *Device)
864{
865 struct netvsc_device *netDevice = Device->Extension;
866 struct rndis_device *rndisDevice = netDevice->Extension;
867
868 DPRINT_ENTER(NETVSC);
869
870
871 RndisFilterHaltDevice(rndisDevice);
872
873 kfree(rndisDevice);
874 netDevice->Extension = NULL;
875
876
877 gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device);
878
879 DPRINT_EXIT(NETVSC);
880
881 return 0;
882}
883
884static void RndisFilterOnCleanup(struct hv_driver *Driver)
885{
886 DPRINT_ENTER(NETVSC);
887
888 DPRINT_EXIT(NETVSC);
889}
890
891static int RndisFilterOnOpen(struct hv_device *Device)
892{
893 int ret;
894 struct netvsc_device *netDevice = Device->Extension;
895
896 DPRINT_ENTER(NETVSC);
897
898 ASSERT(netDevice);
899 ret = RndisFilterOpenDevice(netDevice->Extension);
900
901 DPRINT_EXIT(NETVSC);
902
903 return ret;
904}
905
906static int RndisFilterOnClose(struct hv_device *Device)
907{
908 int ret;
909 struct netvsc_device *netDevice = Device->Extension;
910
911 DPRINT_ENTER(NETVSC);
912
913 ASSERT(netDevice);
914 ret = RndisFilterCloseDevice(netDevice->Extension);
915
916 DPRINT_EXIT(NETVSC);
917
918 return ret;
919}
920
921static int RndisFilterOnSend(struct hv_device *Device,
922 struct hv_netvsc_packet *Packet)
923{
924 int ret;
925 struct rndis_filter_packet *filterPacket;
926 struct rndis_message *rndisMessage;
927 struct rndis_packet *rndisPacket;
928 u32 rndisMessageSize;
929
930 DPRINT_ENTER(NETVSC);
931
932
933 filterPacket = (struct rndis_filter_packet *)Packet->Extension;
934 ASSERT(filterPacket);
935
936 memset(filterPacket, 0, sizeof(struct rndis_filter_packet));
937
938 rndisMessage = &filterPacket->Message;
939 rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet);
940
941 rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG;
942 rndisMessage->MessageLength = Packet->TotalDataBufferLength +
943 rndisMessageSize;
944
945 rndisPacket = &rndisMessage->Message.Packet;
946 rndisPacket->DataOffset = sizeof(struct rndis_packet);
947 rndisPacket->DataLength = Packet->TotalDataBufferLength;
948
949 Packet->IsDataPacket = true;
950 Packet->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT;
951 Packet->PageBuffers[0].Offset =
952 (unsigned long)rndisMessage & (PAGE_SIZE-1);
953 Packet->PageBuffers[0].Length = rndisMessageSize;
954
955
956 filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion;
957 filterPacket->CompletionContext =
958 Packet->Completion.Send.SendCompletionContext;
959
960
961 Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion;
962 Packet->Completion.Send.SendCompletionContext = filterPacket;
963
964 ret = gRndisFilter.InnerDriver.OnSend(Device, Packet);
965 if (ret != 0) {
966
967
968
969
970 Packet->Completion.Send.OnSendCompletion =
971 filterPacket->OnCompletion;
972 Packet->Completion.Send.SendCompletionContext =
973 filterPacket->CompletionContext;
974 }
975
976 DPRINT_EXIT(NETVSC);
977
978 return ret;
979}
980
981static void RndisFilterOnSendCompletion(void *Context)
982{
983 struct rndis_filter_packet *filterPacket = Context;
984
985 DPRINT_ENTER(NETVSC);
986
987
988 filterPacket->OnCompletion(filterPacket->CompletionContext);
989
990 DPRINT_EXIT(NETVSC);
991}
992
993
994static void RndisFilterOnSendRequestCompletion(void *Context)
995{
996 DPRINT_ENTER(NETVSC);
997
998
999 DPRINT_EXIT(NETVSC);
1000}
1001