/*
 * Copyright (c) 2009, Microsoft Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 *
 * Authors:
 *   Haiyang Zhang <haiyangz@microsoft.com>
 *   Hank Janssen  <hjanssen@microsoft.com>
 */
#include <linux/kernel.h>
#include <linux/highmem.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/if_ether.h>

#include "osd.h"
#include "logging.h"
#include "netvsc_api.h"
#include "rndis_filter.h"

/* Data types */
struct rndis_filter_driver_object {
	/* The original driver */
	struct netvsc_driver InnerDriver;
};

enum rndis_device_state {
	RNDIS_DEV_UNINITIALIZED = 0,
	RNDIS_DEV_INITIALIZING,
	RNDIS_DEV_INITIALIZED,
	RNDIS_DEV_DATAINITIALIZED,
};

struct rndis_device {
	struct netvsc_device *NetDevice;

	enum rndis_device_state State;
	u32 LinkStatus;
	atomic_t NewRequestId;

	spinlock_t request_lock;
	struct list_head RequestList;

	unsigned char HwMacAddr[ETH_ALEN];
};

struct rndis_request {
	struct list_head ListEntry;
	struct osd_waitevent *WaitEvent;

	/*
	 * FIXME: We assumed a fixed size response here. If we do ever need to
	 * handle a bigger response, we can either define a max response
	 * message or add a response buffer variable above this field
	 */
	struct rndis_message ResponseMessage;

	/* Simplify allocation by having a netvsc packet inline */
	struct hv_netvsc_packet	Packet;
	struct hv_page_buffer Buffer;
	/* FIXME: We assumed a fixed size request here. */
	struct rndis_message RequestMessage;
};


struct rndis_filter_packet {
	void *CompletionContext;
	void (*OnCompletion)(void *context);
	struct rndis_message Message;
};


static int RndisFilterOnDeviceAdd(struct hv_device *Device,
				  void *AdditionalInfo);

static int RndisFilterOnDeviceRemove(struct hv_device *Device);

static void RndisFilterOnCleanup(struct hv_driver *Driver);

static int RndisFilterOnSend(struct hv_device *Device,
			     struct hv_netvsc_packet *Packet);

static void RndisFilterOnSendCompletion(void *Context);

static void RndisFilterOnSendRequestCompletion(void *Context);


/* The one and only */
static struct rndis_filter_driver_object gRndisFilter;

static struct rndis_device *GetRndisDevice(void)
{
	struct rndis_device *device;

	device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
	if (!device)
		return NULL;

	spin_lock_init(&device->request_lock);

	INIT_LIST_HEAD(&device->RequestList);

	device->State = RNDIS_DEV_UNINITIALIZED;

	return device;
}

static struct rndis_request *GetRndisRequest(struct rndis_device *Device,
					     u32 MessageType,
					     u32 MessageLength)
{
	struct rndis_request *request;
	struct rndis_message *rndisMessage;
	struct rndis_set_request *set;
	unsigned long flags;

	request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
	if (!request)
		return NULL;

	request->WaitEvent = osd_WaitEventCreate();
	if (!request->WaitEvent) {
		kfree(request);
		return NULL;
	}

	rndisMessage = &request->RequestMessage;
	rndisMessage->NdisMessageType = MessageType;
	rndisMessage->MessageLength = MessageLength;

	/*
	 * Set the request id. This field is always after the rndis header for
	 * request/response packet types so we just used the SetRequest as a
	 * template
	 */
	set = &rndisMessage->Message.SetRequest;
	set->RequestId = atomic_inc_return(&Device->NewRequestId);

	/* Add to the request list */
	spin_lock_irqsave(&Device->request_lock, flags);
	list_add_tail(&request->ListEntry, &Device->RequestList);
	spin_unlock_irqrestore(&Device->request_lock, flags);

	return request;
}

static void PutRndisRequest(struct rndis_device *Device,
			    struct rndis_request *Request)
{
	unsigned long flags;

	spin_lock_irqsave(&Device->request_lock, flags);
	list_del(&Request->ListEntry);
	spin_unlock_irqrestore(&Device->request_lock, flags);

	kfree(Request->WaitEvent);
	kfree(Request);
}

static void DumpRndisMessage(struct rndis_message *RndisMessage)
{
	switch (RndisMessage->NdisMessageType) {
	case REMOTE_NDIS_PACKET_MSG:
		DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, "
			   "data offset %u data len %u, # oob %u, "
			   "oob offset %u, oob len %u, pkt offset %u, "
			   "pkt len %u",
			   RndisMessage->MessageLength,
			   RndisMessage->Message.Packet.DataOffset,
			   RndisMessage->Message.Packet.DataLength,
			   RndisMessage->Message.Packet.NumOOBDataElements,
			   RndisMessage->Message.Packet.OOBDataOffset,
			   RndisMessage->Message.Packet.OOBDataLength,
			   RndisMessage->Message.Packet.PerPacketInfoOffset,
			   RndisMessage->Message.Packet.PerPacketInfoLength);
		break;

	case REMOTE_NDIS_INITIALIZE_CMPLT:
		DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT "
			"(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
			"device flags %d, max xfer size 0x%x, max pkts %u, "
			"pkt aligned %u)",
			RndisMessage->MessageLength,
			RndisMessage->Message.InitializeComplete.RequestId,
			RndisMessage->Message.InitializeComplete.Status,
			RndisMessage->Message.InitializeComplete.MajorVersion,
			RndisMessage->Message.InitializeComplete.MinorVersion,
			RndisMessage->Message.InitializeComplete.DeviceFlags,
			RndisMessage->Message.InitializeComplete.MaxTransferSize,
			RndisMessage->Message.InitializeComplete.MaxPacketsPerMessage,
			RndisMessage->Message.InitializeComplete.PacketAlignmentFactor);
		break;

	case REMOTE_NDIS_QUERY_CMPLT:
		DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT "
			"(len %u, id 0x%x, status 0x%x, buf len %u, "
			"buf offset %u)",
			RndisMessage->MessageLength,
			RndisMessage->Message.QueryComplete.RequestId,
			RndisMessage->Message.QueryComplete.Status,
			RndisMessage->Message.QueryComplete.InformationBufferLength,
			RndisMessage->Message.QueryComplete.InformationBufferOffset);
		break;

	case REMOTE_NDIS_SET_CMPLT:
		DPRINT_DBG(NETVSC,
			"REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)",
			RndisMessage->MessageLength,
			RndisMessage->Message.SetComplete.RequestId,
			RndisMessage->Message.SetComplete.Status);
		break;

	case REMOTE_NDIS_INDICATE_STATUS_MSG:
		DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG "
			"(len %u, status 0x%x, buf len %u, buf offset %u)",
			RndisMessage->MessageLength,
			RndisMessage->Message.IndicateStatus.Status,
			RndisMessage->Message.IndicateStatus.StatusBufferLength,
			RndisMessage->Message.IndicateStatus.StatusBufferOffset);
		break;

	default:
		DPRINT_DBG(NETVSC, "0x%x (len %u)",
			RndisMessage->NdisMessageType,
			RndisMessage->MessageLength);
		break;
	}
}

static int RndisFilterSendRequest(struct rndis_device *Device,
				  struct rndis_request *Request)
{
	int ret;
	struct hv_netvsc_packet *packet;

	DPRINT_ENTER(NETVSC);

	/* Setup the packet to send it */
	packet = &Request->Packet;

	packet->IsDataPacket = false;
	packet->TotalDataBufferLength = Request->RequestMessage.MessageLength;
	packet->PageBufferCount = 1;

	packet->PageBuffers[0].Pfn = virt_to_phys(&Request->RequestMessage) >>
					PAGE_SHIFT;
	packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength;
	packet->PageBuffers[0].Offset =
		(unsigned long)&Request->RequestMessage & (PAGE_SIZE - 1);

	packet->Completion.Send.SendCompletionContext = Request;/* packet; */
	packet->Completion.Send.OnSendCompletion =
		RndisFilterOnSendRequestCompletion;
	packet->Completion.Send.SendCompletionTid = (unsigned long)Device;

	ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet);
	DPRINT_EXIT(NETVSC);
	return ret;
}

static void RndisFilterReceiveResponse(struct rndis_device *Device,
				       struct rndis_message *Response)
{
	struct rndis_request *request = NULL;
	bool found = false;
	unsigned long flags;

	DPRINT_ENTER(NETVSC);

	spin_lock_irqsave(&Device->request_lock, flags);
	list_for_each_entry(request, &Device->RequestList, ListEntry) {
		/*
		 * All request/response message contains RequestId as the 1st
		 * field
		 */
		if (request->RequestMessage.Message.InitializeRequest.RequestId
		    == Response->Message.InitializeComplete.RequestId) {
			DPRINT_DBG(NETVSC, "found rndis request for "
				"this response (id 0x%x req type 0x%x res "
				"type 0x%x)",
				request->RequestMessage.Message.InitializeRequest.RequestId,
				request->RequestMessage.NdisMessageType,
				Response->NdisMessageType);

			found = true;
			break;
		}
	}
	spin_unlock_irqrestore(&Device->request_lock, flags);

	if (found) {
		if (Response->MessageLength <= sizeof(struct rndis_message)) {
			memcpy(&request->ResponseMessage, Response,
			       Response->MessageLength);
		} else {
			DPRINT_ERR(NETVSC, "rndis response buffer overflow "
				  "detected (size %u max %zu)",
				  Response->MessageLength,
				  sizeof(struct rndis_filter_packet));

			if (Response->NdisMessageType ==
			    REMOTE_NDIS_RESET_CMPLT) {
				/* does not have a request id field */
				request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW;
			} else {
				request->ResponseMessage.Message.InitializeComplete.Status = STATUS_BUFFER_OVERFLOW;
			}
		}

		osd_WaitEventSet(request->WaitEvent);
	} else {
		DPRINT_ERR(NETVSC, "no rndis request found for this response "
			   "(id 0x%x res type 0x%x)",
			   Response->Message.InitializeComplete.RequestId,
			   Response->NdisMessageType);
	}

	DPRINT_EXIT(NETVSC);
}

static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device,
					     struct rndis_message *Response)
{
	struct rndis_indicate_status *indicate =
			&Response->Message.IndicateStatus;

	if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) {
		gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 1);
	} else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) {
		gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 0);
	} else {
		/*
		 * TODO:
		 */
	}
}

static void RndisFilterReceiveData(struct rndis_device *Device,
				   struct rndis_message *Message,
				   struct hv_netvsc_packet *Packet)
{
	struct rndis_packet *rndisPacket;
	u32 dataOffset;

	DPRINT_ENTER(NETVSC);

	/* empty ethernet frame ?? */
	/* ASSERT(Packet->PageBuffers[0].Length > */
	/* 	RNDIS_MESSAGE_SIZE(struct rndis_packet)); */

	rndisPacket = &Message->Message.Packet;

	/*
	 * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this
	 * netvsc packet (ie TotalDataBufferLength != MessageLength)
	 */

	/* Remove the rndis header and pass it back up the stack */
	dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset;

	Packet->TotalDataBufferLength -= dataOffset;
	Packet->PageBuffers[0].Offset += dataOffset;
	Packet->PageBuffers[0].Length -= dataOffset;

	Packet->IsDataPacket = true;

	gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device,
						   Packet);

	DPRINT_EXIT(NETVSC);
}

static int RndisFilterOnReceive(struct hv_device *Device,
				struct hv_netvsc_packet	*Packet)
{
	struct netvsc_device *netDevice = Device->Extension;
	struct rndis_device *rndisDevice;
	struct rndis_message rndisMessage;
	struct rndis_message *rndisHeader;

	DPRINT_ENTER(NETVSC);

	if (!netDevice)
		return -EINVAL;

	/* Make sure the rndis device state is initialized */
	if (!netDevice->Extension) {
		DPRINT_ERR(NETVSC, "got rndis message but no rndis device..."
			  "dropping this message!");
		DPRINT_EXIT(NETVSC);
		return -1;
	}

	rndisDevice = (struct rndis_device *)netDevice->Extension;
	if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED) {
		DPRINT_ERR(NETVSC, "got rndis message but rndis device "
			   "uninitialized...dropping this message!");
		DPRINT_EXIT(NETVSC);
		return -1;
	}

	rndisHeader = (struct rndis_message *)kmap_atomic(
			pfn_to_page(Packet->PageBuffers[0].Pfn), KM_IRQ0);

	rndisHeader = (void *)((unsigned long)rndisHeader +
			Packet->PageBuffers[0].Offset);

	/* Make sure we got a valid rndis message */
	/*
	 * FIXME: There seems to be a bug in set completion msg where its
	 * MessageLength is 16 bytes but the ByteCount field in the xfer page
	 * range shows 52 bytes
	 * */
#if 0
	if (Packet->TotalDataBufferLength != rndisHeader->MessageLength) {
		kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset,
			      KM_IRQ0);

		DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u "
			   "bytes got %u)...dropping this message!",
			   rndisHeader->MessageLength,
			   Packet->TotalDataBufferLength);
		DPRINT_EXIT(NETVSC);
		return -1;
	}
#endif

	if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) &&
	    (rndisHeader->MessageLength > sizeof(struct rndis_message))) {
		DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow "
			   "detected (got %u, max %zu)...marking it an error!",
			   rndisHeader->MessageLength,
			   sizeof(struct rndis_message));
	}

	memcpy(&rndisMessage, rndisHeader,
		(rndisHeader->MessageLength > sizeof(struct rndis_message)) ?
			sizeof(struct rndis_message) :
			rndisHeader->MessageLength);

	kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, KM_IRQ0);

	DumpRndisMessage(&rndisMessage);

	switch (rndisMessage.NdisMessageType) {
	case REMOTE_NDIS_PACKET_MSG:
		/* data msg */
		RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet);
		break;

	case REMOTE_NDIS_INITIALIZE_CMPLT:
	case REMOTE_NDIS_QUERY_CMPLT:
	case REMOTE_NDIS_SET_CMPLT:
	/* case REMOTE_NDIS_RESET_CMPLT: */
	/* case REMOTE_NDIS_KEEPALIVE_CMPLT: */
		/* completion msgs */
		RndisFilterReceiveResponse(rndisDevice, &rndisMessage);
		break;

	case REMOTE_NDIS_INDICATE_STATUS_MSG:
		/* notification msgs */
		RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage);
		break;
	default:
		DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)",
			   rndisMessage.NdisMessageType,
			   rndisMessage.MessageLength);
		break;
	}

	DPRINT_EXIT(NETVSC);
	return 0;
}

static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid,
				  void *Result, u32 *ResultSize)
{
	struct rndis_request *request;
	u32 inresultSize = *ResultSize;
	struct rndis_query_request *query;
	struct rndis_query_complete *queryComplete;
	int ret = 0;

	DPRINT_ENTER(NETVSC);

	if (!Result)
		return -EINVAL;

	*ResultSize = 0;
	request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG,
			RNDIS_MESSAGE_SIZE(struct rndis_query_request));
	if (!request) {
		ret = -1;
		goto Cleanup;
	}

	/* Setup the rndis query */
	query = &request->RequestMessage.Message.QueryRequest;
	query->Oid = Oid;
	query->InformationBufferOffset = sizeof(struct rndis_query_request);
	query->InformationBufferLength = 0;
	query->DeviceVcHandle = 0;

	ret = RndisFilterSendRequest(Device, request);
	if (ret != 0)
		goto Cleanup;

	osd_WaitEventWait(request->WaitEvent);

	/* Copy the response back */
	queryComplete = &request->ResponseMessage.Message.QueryComplete;

	if (queryComplete->InformationBufferLength > inresultSize) {
		ret = -1;
		goto Cleanup;
	}

	memcpy(Result,
	       (void *)((unsigned long)queryComplete +
			 queryComplete->InformationBufferOffset),
	       queryComplete->InformationBufferLength);

	*ResultSize = queryComplete->InformationBufferLength;

Cleanup:
	if (request)
		PutRndisRequest(Device, request);
	DPRINT_EXIT(NETVSC);

	return ret;
}

static int RndisFilterQueryDeviceMac(struct rndis_device *Device)
{
	u32 size = ETH_ALEN;

	return RndisFilterQueryDevice(Device,
				      RNDIS_OID_802_3_PERMANENT_ADDRESS,
				      Device->HwMacAddr, &size);
}

static int RndisFilterQueryDeviceLinkStatus(struct rndis_device *Device)
{
	u32 size = sizeof(u32);

	return RndisFilterQueryDevice(Device,
				      RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
				      &Device->LinkStatus, &size);
}

static int RndisFilterSetPacketFilter(struct rndis_device *Device,
				      u32 NewFilter)
{
	struct rndis_request *request;
	struct rndis_set_request *set;
	struct rndis_set_complete *setComplete;
	u32 status;
	int ret;

	DPRINT_ENTER(NETVSC);

	/* ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= */
	/* 	sizeof(struct rndis_message)); */

	request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG,
			RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
			sizeof(u32));
	if (!request) {
		ret = -1;
		goto Cleanup;
	}

	/* Setup the rndis set */
	set = &request->RequestMessage.Message.SetRequest;
	set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
	set->InformationBufferLength = sizeof(u32);
	set->InformationBufferOffset = sizeof(struct rndis_set_request);

	memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
	       &NewFilter, sizeof(u32));

	ret = RndisFilterSendRequest(Device, request);
	if (ret != 0)
		goto Cleanup;

	ret = osd_WaitEventWaitEx(request->WaitEvent, 2000/*2sec*/);
	if (!ret) {
		ret = -1;
		DPRINT_ERR(NETVSC, "timeout before we got a set response...");
		/*
		 * We cant deallocate the request since we may still receive a
		 * send completion for it.
		 */
		goto Exit;
	} else {
		if (ret > 0)
			ret = 0;
		setComplete = &request->ResponseMessage.Message.SetComplete;
		status = setComplete->Status;
	}

Cleanup:
	if (request)
		PutRndisRequest(Device, request);
Exit:
	DPRINT_EXIT(NETVSC);

	return ret;
}

int RndisFilterInit(struct netvsc_driver *Driver)
{
	DPRINT_ENTER(NETVSC);

	DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd",
		   sizeof(struct rndis_filter_packet));

	Driver->RequestExtSize = sizeof(struct rndis_filter_packet);

	/* Driver->Context = rndisDriver; */

	memset(&gRndisFilter, 0, sizeof(struct rndis_filter_driver_object));

	/*rndisDriver->Driver = Driver;

	ASSERT(Driver->OnLinkStatusChanged);
	rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/

	/* Save the original dispatch handlers before we override it */
	gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd;
	gRndisFilter.InnerDriver.Base.OnDeviceRemove =
					Driver->Base.OnDeviceRemove;
	gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup;

	/* ASSERT(Driver->OnSend); */
	/* ASSERT(Driver->OnReceiveCallback); */
	gRndisFilter.InnerDriver.OnSend = Driver->OnSend;
	gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback;
	gRndisFilter.InnerDriver.OnLinkStatusChanged =
					Driver->OnLinkStatusChanged;

	/* Override */
	Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd;
	Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove;
	Driver->Base.OnCleanup = RndisFilterOnCleanup;
	Driver->OnSend = RndisFilterOnSend;
	/* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */
	Driver->OnReceiveCallback = RndisFilterOnReceive;

	DPRINT_EXIT(NETVSC);

	return 0;
}

static int RndisFilterInitDevice(struct rndis_device *Device)
{
	struct rndis_request *request;
	struct rndis_initialize_request *init;
	struct rndis_initialize_complete *initComplete;
	u32 status;
	int ret;

	DPRINT_ENTER(NETVSC);

	request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG,
			RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
	if (!request) {
		ret = -1;
		goto Cleanup;
	}

	/* Setup the rndis set */
	init = &request->RequestMessage.Message.InitializeRequest;
	init->MajorVersion = RNDIS_MAJOR_VERSION;
	init->MinorVersion = RNDIS_MINOR_VERSION;
	/* FIXME: Use 1536 - rounded ethernet frame size */
	init->MaxTransferSize = 2048;

	Device->State = RNDIS_DEV_INITIALIZING;

	ret = RndisFilterSendRequest(Device, request);
	if (ret != 0) {
		Device->State = RNDIS_DEV_UNINITIALIZED;
		goto Cleanup;
	}

	osd_WaitEventWait(request->WaitEvent);

	initComplete = &request->ResponseMessage.Message.InitializeComplete;
	status = initComplete->Status;
	if (status == RNDIS_STATUS_SUCCESS) {
		Device->State = RNDIS_DEV_INITIALIZED;
		ret = 0;
	} else {
		Device->State = RNDIS_DEV_UNINITIALIZED;
		ret = -1;
	}

Cleanup:
	if (request)
		PutRndisRequest(Device, request);
	DPRINT_EXIT(NETVSC);

	return ret;
}

static void RndisFilterHaltDevice(struct rndis_device *Device)
{
	struct rndis_request *request;
	struct rndis_halt_request *halt;

	DPRINT_ENTER(NETVSC);

	/* Attempt to do a rndis device halt */
	request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG,
				RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
	if (!request)
		goto Cleanup;

	/* Setup the rndis set */
	halt = &request->RequestMessage.Message.HaltRequest;
	halt->RequestId = atomic_inc_return(&Device->NewRequestId);

	/* Ignore return since this msg is optional. */
	RndisFilterSendRequest(Device, request);

	Device->State = RNDIS_DEV_UNINITIALIZED;

Cleanup:
	if (request)
		PutRndisRequest(Device, request);
	DPRINT_EXIT(NETVSC);
	return;
}

static int RndisFilterOpenDevice(struct rndis_device *Device)
{
	int ret;

	DPRINT_ENTER(NETVSC);

	if (Device->State != RNDIS_DEV_INITIALIZED)
		return 0;

	ret = RndisFilterSetPacketFilter(Device,
					 NDIS_PACKET_TYPE_BROADCAST |
					 NDIS_PACKET_TYPE_ALL_MULTICAST |
					 NDIS_PACKET_TYPE_DIRECTED);
	if (ret == 0)
		Device->State = RNDIS_DEV_DATAINITIALIZED;

	DPRINT_EXIT(NETVSC);
	return ret;
}

static int RndisFilterCloseDevice(struct rndis_device *Device)
{
	int ret;

	DPRINT_ENTER(NETVSC);

	if (Device->State != RNDIS_DEV_DATAINITIALIZED)
		return 0;

	ret = RndisFilterSetPacketFilter(Device, 0);
	if (ret == 0)
		Device->State = RNDIS_DEV_INITIALIZED;

	DPRINT_EXIT(NETVSC);

	return ret;
}

static int RndisFilterOnDeviceAdd(struct hv_device *Device,
				  void *AdditionalInfo)
{
	int ret;
	struct netvsc_device *netDevice;
	struct rndis_device *rndisDevice;
	struct netvsc_device_info *deviceInfo = AdditionalInfo;

	DPRINT_ENTER(NETVSC);

	rndisDevice = GetRndisDevice();
	if (!rndisDevice) {
		DPRINT_EXIT(NETVSC);
		return -1;
	}

	DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);

	/*
	 * Let the inner driver handle this first to create the netvsc channel
	 * NOTE! Once the channel is created, we may get a receive callback
	 * (RndisFilterOnReceive()) before this call is completed
	 */
	ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo);
	if (ret != 0) {
		kfree(rndisDevice);
		DPRINT_EXIT(NETVSC);
		return ret;
	}


	/* Initialize the rndis device */
	netDevice = Device->Extension;
	/* ASSERT(netDevice); */
	/* ASSERT(netDevice->Device); */

	netDevice->Extension = rndisDevice;
	rndisDevice->NetDevice = netDevice;

	/* Send the rndis initialization message */
	ret = RndisFilterInitDevice(rndisDevice);
	if (ret != 0) {
		/*
		 * TODO: If rndis init failed, we will need to shut down the
		 * channel
		 */
	}

	/* Get the mac address */
	ret = RndisFilterQueryDeviceMac(rndisDevice);
	if (ret != 0) {
		/*
		 * TODO: shutdown rndis device and the channel
		 */
	}

	DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM",
		    rndisDevice, rndisDevice->HwMacAddr);

	memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, ETH_ALEN);

	RndisFilterQueryDeviceLinkStatus(rndisDevice);

	deviceInfo->LinkState = rndisDevice->LinkStatus;
	DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice,
		    ((deviceInfo->LinkState) ? ("down") : ("up")));

	DPRINT_EXIT(NETVSC);

	return ret;
}

static int RndisFilterOnDeviceRemove(struct hv_device *Device)
{
	struct netvsc_device *netDevice = Device->Extension;
	struct rndis_device *rndisDevice = netDevice->Extension;

	DPRINT_ENTER(NETVSC);

	/* Halt and release the rndis device */
	RndisFilterHaltDevice(rndisDevice);

	kfree(rndisDevice);
	netDevice->Extension = NULL;

	/* Pass control to inner driver to remove the device */
	gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device);

	DPRINT_EXIT(NETVSC);

	return 0;
}

static void RndisFilterOnCleanup(struct hv_driver *Driver)
{
	DPRINT_ENTER(NETVSC);

	DPRINT_EXIT(NETVSC);
}

int RndisFilterOnOpen(struct hv_device *Device)
{
	int ret;
	struct netvsc_device *netDevice = Device->Extension;

	DPRINT_ENTER(NETVSC);

	if (!netDevice)
		return -EINVAL;

	ret = RndisFilterOpenDevice(netDevice->Extension);

	DPRINT_EXIT(NETVSC);

	return ret;
}

int RndisFilterOnClose(struct hv_device *Device)
{
	int ret;
	struct netvsc_device *netDevice = Device->Extension;

	DPRINT_ENTER(NETVSC);

	if (!netDevice)
		return -EINVAL;

	ret = RndisFilterCloseDevice(netDevice->Extension);

	DPRINT_EXIT(NETVSC);

	return ret;
}

static int RndisFilterOnSend(struct hv_device *Device,
			     struct hv_netvsc_packet *Packet)
{
	int ret;
	struct rndis_filter_packet *filterPacket;
	struct rndis_message *rndisMessage;
	struct rndis_packet *rndisPacket;
	u32 rndisMessageSize;

	DPRINT_ENTER(NETVSC);

	/* Add the rndis header */
	filterPacket = (struct rndis_filter_packet *)Packet->Extension;
	/* ASSERT(filterPacket); */

	memset(filterPacket, 0, sizeof(struct rndis_filter_packet));

	rndisMessage = &filterPacket->Message;
	rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet);

	rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG;
	rndisMessage->MessageLength = Packet->TotalDataBufferLength +
				      rndisMessageSize;

	rndisPacket = &rndisMessage->Message.Packet;
	rndisPacket->DataOffset = sizeof(struct rndis_packet);
	rndisPacket->DataLength = Packet->TotalDataBufferLength;

	Packet->IsDataPacket = true;
	Packet->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT;
	Packet->PageBuffers[0].Offset =
			(unsigned long)rndisMessage & (PAGE_SIZE-1);
	Packet->PageBuffers[0].Length = rndisMessageSize;

	/* Save the packet send completion and context */
	filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion;
	filterPacket->CompletionContext =
				Packet->Completion.Send.SendCompletionContext;

	/* Use ours */
	Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion;
	Packet->Completion.Send.SendCompletionContext = filterPacket;

	ret = gRndisFilter.InnerDriver.OnSend(Device, Packet);
	if (ret != 0) {
		/*
		 * Reset the completion to originals to allow retries from
		 * above
		 */
		Packet->Completion.Send.OnSendCompletion =
				filterPacket->OnCompletion;
		Packet->Completion.Send.SendCompletionContext =
				filterPacket->CompletionContext;
	}

	DPRINT_EXIT(NETVSC);

	return ret;
}

static void RndisFilterOnSendCompletion(void *Context)
{
	struct rndis_filter_packet *filterPacket = Context;

	DPRINT_ENTER(NETVSC);

	/* Pass it back to the original handler */
	filterPacket->OnCompletion(filterPacket->CompletionContext);

	DPRINT_EXIT(NETVSC);
}


static void RndisFilterOnSendRequestCompletion(void *Context)
{
	DPRINT_ENTER(NETVSC);

	/* Noop */
	DPRINT_EXIT(NETVSC);
}
