/*
 * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

#include "ol_if_athvar.h"
#include "htc_debug.h"
#include "htc_internal.h"
#include <cdf_nbuf.h>           /* cdf_nbuf_t */
#include <cdf_types.h>          /* cdf_print */
#include <hif.h>
#include <cds_get_bin.h>
#include "epping_main.h"
#include "hif_io32.h"

#ifdef DEBUG
static ATH_DEBUG_MASK_DESCRIPTION g_htc_debug_description[] = {
	{ATH_DEBUG_SEND, "Send"},
	{ATH_DEBUG_RECV, "Recv"},
	{ATH_DEBUG_SYNC, "Sync"},
	{ATH_DEBUG_DUMP, "Dump Data (RX or TX)"},
	{ATH_DEBUG_SETUP, "Setup"},
};

ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc,
				 "htc",
				 "Host Target Communications",
				 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO |
				 ATH_DEBUG_SETUP,
				 ATH_DEBUG_DESCRIPTION_COUNT
					 (g_htc_debug_description),
				 g_htc_debug_description);

#endif

extern unsigned int htc_credit_flow;

static void reset_endpoint_states(HTC_TARGET *target);

static void destroy_htc_tx_ctrl_packet(HTC_PACKET *pPacket)
{
	cdf_nbuf_t netbuf;
	netbuf = (cdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("free ctrl netbuf :0x%p \n", netbuf));
	if (netbuf != NULL) {
		cdf_nbuf_free(netbuf);
	}

	cdf_mem_free(pPacket);
}

static HTC_PACKET *build_htc_tx_ctrl_packet(cdf_device_t osdev)
{
	HTC_PACKET *pPacket = NULL;
	cdf_nbuf_t netbuf;

	do {
		pPacket = (HTC_PACKET *) cdf_mem_malloc(sizeof(HTC_PACKET));
		if (NULL == pPacket) {
			break;
		}
		A_MEMZERO(pPacket, sizeof(HTC_PACKET));
		netbuf =
			cdf_nbuf_alloc(osdev, HTC_CONTROL_BUFFER_SIZE, 20, 4, true);
		if (NULL == netbuf) {
			cdf_mem_free(pPacket);
			pPacket = NULL;
			cdf_print("%s: nbuf alloc failed\n", __func__);
			break;
		}
		AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
				("alloc ctrl netbuf :0x%p \n", netbuf));
		SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf);
	} while (false);

	return pPacket;
}

void htc_free_control_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket)
{

#ifdef TODO_FIXME
	LOCK_HTC(target);
	HTC_PACKET_ENQUEUE(&target->ControlBufferTXFreeList, pPacket);
	UNLOCK_HTC(target);
	/* TODO_FIXME netbufs cannot be RESET! */
#else
	destroy_htc_tx_ctrl_packet(pPacket);
#endif

}

HTC_PACKET *htc_alloc_control_tx_packet(HTC_TARGET *target)
{
#ifdef TODO_FIXME
	HTC_PACKET *pPacket;

	LOCK_HTC(target);
	pPacket = htc_packet_dequeue(&target->ControlBufferTXFreeList);
	UNLOCK_HTC(target);

	return pPacket;
#else
	return build_htc_tx_ctrl_packet(target->osdev);
#endif
}

/* Set the target failure handling callback */
void htc_set_target_failure_callback(HTC_HANDLE HTCHandle,
				     HTC_TARGET_FAILURE Callback)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	target->HTCInitInfo.TargetFailure = Callback;
}

void htc_dump(HTC_HANDLE HTCHandle, uint8_t CmdId, bool start)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	hif_dump(target->hif_dev, CmdId, start);
}

/* cleanup the HTC instance */
static void htc_cleanup(HTC_TARGET *target)
{
	HTC_PACKET *pPacket;
	/* cdf_nbuf_t netbuf; */

	if (target->hif_dev != NULL) {
		hif_detach_htc(target->hif_dev);
		target->hif_dev = NULL;
	}

	while (true) {
		pPacket = allocate_htc_packet_container(target);
		if (NULL == pPacket) {
			break;
		}
		cdf_mem_free(pPacket);
	}

	pPacket = target->pBundleFreeList;
	while (pPacket) {
		HTC_PACKET *pPacketTmp = (HTC_PACKET *) pPacket->ListLink.pNext;
		cdf_mem_free(pPacket);
		pPacket = pPacketTmp;
	}
#ifdef TODO_FIXME
	while (true) {
		pPacket = htc_alloc_control_tx_packet(target);
		if (NULL == pPacket) {
			break;
		}
		netbuf = (cdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
		if (netbuf != NULL) {
			cdf_nbuf_free(netbuf);
		}

		cdf_mem_free(pPacket);
	}
#endif

	cdf_spinlock_destroy(&target->HTCLock);
	cdf_spinlock_destroy(&target->HTCRxLock);
	cdf_spinlock_destroy(&target->HTCTxLock);
	cdf_spinlock_destroy(&target->HTCCreditLock);

	/* free our instance */
	cdf_mem_free(target);
}

/* registered target arrival callback from the HIF layer */
HTC_HANDLE htc_create(void *ol_sc, HTC_INIT_INFO *pInfo, cdf_device_t osdev)
{
	struct hif_msg_callbacks htcCallbacks;
	HTC_ENDPOINT *pEndpoint = NULL;
	HTC_TARGET *target = NULL;
	int i;

	if (ol_sc == NULL) {
		HTC_ERROR("%s: ol_sc = NULL", __func__);
		return NULL;
	}
	HTC_TRACE("+htc_create ..  HIF :%p", ol_sc);

	A_REGISTER_MODULE_DEBUG_INFO(htc);

	target = (HTC_TARGET *) cdf_mem_malloc(sizeof(HTC_TARGET));
	if (target == NULL) {
		HTC_ERROR("%s: Unable to allocate memory", __func__);
		return NULL;
	}

	A_MEMZERO(target, sizeof(HTC_TARGET));

	cdf_spinlock_init(&target->HTCLock);
	cdf_spinlock_init(&target->HTCRxLock);
	cdf_spinlock_init(&target->HTCTxLock);
	cdf_spinlock_init(&target->HTCCreditLock);

	do {
		A_MEMCPY(&target->HTCInitInfo, pInfo, sizeof(HTC_INIT_INFO));
		target->host_handle = pInfo->pContext;
		target->osdev = osdev;

		reset_endpoint_states(target);

		INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);

		for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) {
			HTC_PACKET *pPacket =
				(HTC_PACKET *) cdf_mem_malloc(sizeof(HTC_PACKET));
			if (pPacket != NULL) {
				A_MEMZERO(pPacket, sizeof(HTC_PACKET));
				free_htc_packet_container(target, pPacket);
			}
		}

#ifdef TODO_FIXME
		for (i = 0; i < NUM_CONTROL_TX_BUFFERS; i++) {
			pPacket = build_htc_tx_ctrl_packet();
			if (NULL == pPacket) {
				break;
			}
			htc_free_control_tx_packet(target, pPacket);
		}
#endif

		/* setup HIF layer callbacks */
		cdf_mem_zero(&htcCallbacks, sizeof(struct hif_msg_callbacks));
		htcCallbacks.Context = target;
		htcCallbacks.rxCompletionHandler = htc_rx_completion_handler;
		htcCallbacks.txCompletionHandler = htc_tx_completion_handler;
		htcCallbacks.txResourceAvailHandler = htc_tx_resource_avail_handler;
		htcCallbacks.fwEventHandler = htc_fw_event_handler;
		target->hif_dev = ol_sc;

		/* Get HIF default pipe for HTC message exchange */
		pEndpoint = &target->EndPoint[ENDPOINT_0];

		hif_post_init(target->hif_dev, target, &htcCallbacks);
		hif_get_default_pipe(target->hif_dev, &pEndpoint->UL_PipeID,
				     &pEndpoint->DL_PipeID);

	} while (false);

	htc_recv_init(target);

	HTC_TRACE("-htc_create: (0x%p)", target);

	return (HTC_HANDLE) target;
}

void htc_destroy(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
			("+htc_destroy ..  Destroying :0x%p\n", target));
	if (target)
		htc_cleanup(target);
	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_destroy\n"));
}

/* get the low level HIF device for the caller , the caller may wish to do low level
 * HIF requests */
void *htc_get_hif_device(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	return target->hif_dev;
}

void htc_control_tx_complete(void *Context, HTC_PACKET *pPacket)
{
	HTC_TARGET *target = (HTC_TARGET *) Context;
	AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
			("+-htc_control_tx_complete 0x%p (l:%d) \n", pPacket,
			 pPacket->ActualLength));
	htc_free_control_tx_packet(target, pPacket);
}

/* TODO, this is just a temporary max packet size */
#define MAX_MESSAGE_SIZE 1536

/**
 * htc_setup_target_buffer_assignments() - setup target buffer assignments
 * @target: HTC Target Pointer
 *
 * Return: A_STATUS
 */
A_STATUS htc_setup_target_buffer_assignments(HTC_TARGET *target)
{
	HTC_SERVICE_TX_CREDIT_ALLOCATION *pEntry;
	A_STATUS status;
	int credits;
	int creditsPerMaxMsg;

	creditsPerMaxMsg = MAX_MESSAGE_SIZE / target->TargetCreditSize;
	if (MAX_MESSAGE_SIZE % target->TargetCreditSize) {
		creditsPerMaxMsg++;
	}

	/* TODO, this should be configured by the caller! */

	credits = target->TotalTransmitCredits;
	pEntry = &target->ServiceTxAllocTable[0];

	/*
	 * Allocate all credists/HTC buffers to WMI.
	 * no buffers are used/required for data. data always
	 * remains on host.
	 */
	status = A_OK;
	pEntry++;
	pEntry->ServiceID = WMI_CONTROL_SVC;
	pEntry->CreditAllocation = credits;

	if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
		/* endpoint ping is a testing tool directly on top of HTC in
		 * both target and host sides.
		 * In target side, the endppint ping fw has no wlan stack and the
		 * FW mboxping app directly sits on HTC and it simply drops
		 * or loops back TX packets. For rx perf, FW mboxping app
		 * generates packets and passes packets to HTC to send to host.
		 * There is no WMI mesage exchanges between host and target
		 * in endpoint ping case.
		 * In host side, the endpoint ping driver is a Ethernet driver
		 * and it directly sits on HTC. Only HIF, HTC, CDF, ADF are
		 * used by the endpoint ping driver. There is no wifi stack
		 * at all in host side also. For tx perf use case,
		 * the user space mboxping app sends the raw packets to endpoint
		 * ping driver and it directly forwards to HTC for transmission
		 * to stress the bus. For the rx perf, HTC passes the received
		 * packets to endpoint ping driver and it is passed to the user
		 * space through the Ethernet interface.
		 * For credit allocation, in SDIO bus case, only BE service is
		 * used for tx/rx perf testing so that all credits are given
		 * to BE service. In PCIe and USB bus case, endpoint ping uses both
		 * BE and BK services to stress the bus so that the total credits
		 * are equally distributed to BE and BK services.
		 */
		pEntry->ServiceID = WMI_DATA_BE_SVC;
		pEntry->CreditAllocation = (credits >> 1);

		pEntry++;
		pEntry->ServiceID = WMI_DATA_BK_SVC;
		pEntry->CreditAllocation = (credits >> 1);
	}

	if (A_SUCCESS(status)) {
		int i;
		for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) {
			if (target->ServiceTxAllocTable[i].ServiceID != 0) {
				AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
						("HTC Service Index : %d TX : 0x%2.2X : alloc:%d \n",
						 i,
						 target->ServiceTxAllocTable[i].
						 ServiceID,
						 target->ServiceTxAllocTable[i].
						 CreditAllocation));
			}
		}
	}

	return status;
}

A_UINT8 htc_get_credit_allocation(HTC_TARGET *target, A_UINT16 ServiceID)
{
	A_UINT8 allocation = 0;
	int i;

	for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) {
		if (target->ServiceTxAllocTable[i].ServiceID == ServiceID) {
			allocation =
				target->ServiceTxAllocTable[i].CreditAllocation;
		}
	}

	if (0 == allocation) {
		AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
				("HTC Service TX : 0x%2.2X : allocation is zero! \n",
				 ServiceID));
	}

	return allocation;
}

A_STATUS htc_wait_target(HTC_HANDLE HTCHandle)
{
	A_STATUS status = A_OK;
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	HTC_READY_EX_MSG *pReadyMsg;
	HTC_SERVICE_CONNECT_REQ connect;
	HTC_SERVICE_CONNECT_RESP resp;
	HTC_READY_MSG *rdy_msg;
	A_UINT16 htc_rdy_msg_id;

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
			("htc_wait_target - Enter (target:0x%p) \n", HTCHandle));
	AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n"));

	do {

		status = hif_start(target->hif_dev);
		if (A_FAILED(status)) {
			AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("hif_start failed\n"));
			break;
		}

		status = htc_wait_recv_ctrl_message(target);

		if (A_FAILED(status)) {
			break;
		}

		if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) {
			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
					("Invalid HTC Ready Msg Len:%d! \n",
					 target->CtrlResponseLength));
			status = A_ECOMM;
			break;
		}

		pReadyMsg = (HTC_READY_EX_MSG *) target->CtrlResponseBuffer;

		rdy_msg = &pReadyMsg->Version2_0_Info;
		htc_rdy_msg_id =
			HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID);
		if (htc_rdy_msg_id != HTC_MSG_READY_ID) {
			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
					("Invalid HTC Ready Msg : 0x%X ! \n",
					 htc_rdy_msg_id));
			status = A_ECOMM;
			break;
		}

		target->TotalTransmitCredits =
			HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITCOUNT);
		target->TargetCreditSize =
			(int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE);
		target->MaxMsgsPerHTCBundle =
			(A_UINT8) pReadyMsg->MaxMsgsPerHTCBundle;
		/* for old fw this value is set to 0. But the minimum value should be 1,
		 * i.e., no bundling */
		if (target->MaxMsgsPerHTCBundle < 1)
			target->MaxMsgsPerHTCBundle = 1;

		AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
				("Target Ready! : transmit resources : %d size:%d, MaxMsgsPerHTCBundle = %d\n",
				 target->TotalTransmitCredits,
				 target->TargetCreditSize,
				 target->MaxMsgsPerHTCBundle));

		if ((0 == target->TotalTransmitCredits)
		    || (0 == target->TargetCreditSize)) {
			status = A_ECOMM;
			break;
		}
		/* done processing */
		target->CtrlResponseProcessing = false;

		htc_setup_target_buffer_assignments(target);

		/* setup our pseudo HTC control endpoint connection */
		A_MEMZERO(&connect, sizeof(connect));
		A_MEMZERO(&resp, sizeof(resp));
		connect.EpCallbacks.pContext = target;
		connect.EpCallbacks.EpTxComplete = htc_control_tx_complete;
		connect.EpCallbacks.EpRecv = htc_control_rx_complete;
		connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS;
		connect.ServiceID = HTC_CTRL_RSVD_SVC;

		/* connect fake service */
		status = htc_connect_service((HTC_HANDLE) target,
					     &connect, &resp);

	} while (false);

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_wait_target - Exit (%d)\n", status));
	AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("-HWT\n"));
	return status;
}

/* start HTC, this is called after all services are connected */
static A_STATUS htc_config_target_hif_pipe(HTC_TARGET *target)
{

	return A_OK;
}

static void reset_endpoint_states(HTC_TARGET *target)
{
	HTC_ENDPOINT *pEndpoint;
	int i;

	for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
		pEndpoint = &target->EndPoint[i];
		pEndpoint->ServiceID = 0;
		pEndpoint->MaxMsgLength = 0;
		pEndpoint->MaxTxQueueDepth = 0;
		pEndpoint->Id = i;
		INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
		INIT_HTC_PACKET_QUEUE(&pEndpoint->TxLookupQueue);
		INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBufferHoldQueue);
		pEndpoint->target = target;
		/* pEndpoint->TxCreditFlowEnabled = (A_BOOL)htc_credit_flow; */
		pEndpoint->TxCreditFlowEnabled = (A_BOOL) 1;
		cdf_atomic_init(&pEndpoint->TxProcessCount);
	}
}

A_STATUS htc_start(HTC_HANDLE HTCHandle)
{
	cdf_nbuf_t netbuf;
	A_STATUS status = A_OK;
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	HTC_SETUP_COMPLETE_EX_MSG *pSetupComp;
	HTC_PACKET *pSendPacket;

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Enter\n"));

	do {

		htc_config_target_hif_pipe(target);

		/* allocate a buffer to send */
		pSendPacket = htc_alloc_control_tx_packet(target);
		if (NULL == pSendPacket) {
			AR_DEBUG_ASSERT(false);
			cdf_print("%s: allocControlTxPacket failed\n",
				  __func__);
			status = A_NO_MEMORY;
			break;
		}

		netbuf =
			(cdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket);
		/* assemble setup complete message */
		cdf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
		pSetupComp =
			(HTC_SETUP_COMPLETE_EX_MSG *) cdf_nbuf_data(netbuf);
		A_MEMZERO(pSetupComp, sizeof(HTC_SETUP_COMPLETE_EX_MSG));

		HTC_SET_FIELD(pSetupComp, HTC_SETUP_COMPLETE_EX_MSG,
			      MESSAGEID, HTC_MSG_SETUP_COMPLETE_EX_ID);

		if (!htc_credit_flow) {
			AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
					("HTC will not use TX credit flow control\n"));
			pSetupComp->SetupFlags |=
				HTC_SETUP_COMPLETE_FLAGS_DISABLE_TX_CREDIT_FLOW;
		} else {
			AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
					("HTC using TX credit flow control\n"));
		}

#ifdef HIF_SDIO
#if ENABLE_BUNDLE_RX
		if (HTC_ENABLE_BUNDLE(target))
			pSetupComp->SetupFlags |=
				HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
#endif /* ENABLE_BUNDLE_RX */
#endif /* HIF_SDIO */

		SET_HTC_PACKET_INFO_TX(pSendPacket,
				       NULL,
				       (A_UINT8 *) pSetupComp,
				       sizeof(HTC_SETUP_COMPLETE_EX_MSG),
				       ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);

		status = htc_send_pkt((HTC_HANDLE) target, pSendPacket);
		if (A_FAILED(status)) {
			break;
		}

	} while (false);

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Exit\n"));
	return status;
}

/*flush all queued buffers for surpriseremove case*/
void htc_flush_surprise_remove(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	int i;
	HTC_ENDPOINT *pEndpoint;
#ifdef RX_SG_SUPPORT
	cdf_nbuf_t netbuf;
	cdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
#endif

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_flush_surprise_remove \n"));

	/* cleanup endpoints */
	for (i = 0; i < ENDPOINT_MAX; i++) {
		pEndpoint = &target->EndPoint[i];
		htc_flush_rx_hold_queue(target, pEndpoint);
		htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
	}

	hif_flush_surprise_remove(target->hif_dev);

#ifdef RX_SG_SUPPORT
	LOCK_HTC_RX(target);
	while ((netbuf = cdf_nbuf_queue_remove(rx_sg_queue)) != NULL) {
		cdf_nbuf_free(netbuf);
	}
	RESET_RX_SG_CONFIG(target);
	UNLOCK_HTC_RX(target);
#endif

	reset_endpoint_states(target);

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_flush_surprise_remove \n"));
}

/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
void htc_stop(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	int i;
	HTC_ENDPOINT *pEndpoint;
#ifdef RX_SG_SUPPORT
	cdf_nbuf_t netbuf;
	cdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
#endif

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_stop \n"));

	/* cleanup endpoints */
	for (i = 0; i < ENDPOINT_MAX; i++) {
		pEndpoint = &target->EndPoint[i];
		htc_flush_rx_hold_queue(target, pEndpoint);
		htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
		if (pEndpoint->ul_is_polled) {
			cdf_softirq_timer_cancel(&pEndpoint->ul_poll_timer);
			cdf_softirq_timer_free(&pEndpoint->ul_poll_timer);
		}
	}

	/* Note: htc_flush_endpoint_tx for all endpoints should be called before
	 * hif_stop - otherwise htc_tx_completion_handler called from
	 * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer,
	 * might queue the packet again to HIF Layer - which could cause tx
	 * buffer leak
	 */

	hif_stop(target->hif_dev);

#ifdef RX_SG_SUPPORT
	LOCK_HTC_RX(target);
	while ((netbuf = cdf_nbuf_queue_remove(rx_sg_queue)) != NULL) {
		cdf_nbuf_free(netbuf);
	}
	RESET_RX_SG_CONFIG(target);
	UNLOCK_HTC_RX(target);
#endif

	reset_endpoint_states(target);

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_stop \n"));
}

void htc_dump_credit_states(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	HTC_ENDPOINT *pEndpoint;
	int i;

	for (i = 0; i < ENDPOINT_MAX; i++) {
		pEndpoint = &target->EndPoint[i];
		if (0 == pEndpoint->ServiceID) {
			continue;
		}
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				("--- EP : %d  ServiceID: 0x%X    --------------\n",
				 pEndpoint->Id, pEndpoint->ServiceID));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				(" TxCredits          : %d \n",
				 pEndpoint->TxCredits));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				(" TxCreditSize       : %d \n",
				 pEndpoint->TxCreditSize));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				(" TxCreditsPerMaxMsg : %d \n",
				 pEndpoint->TxCreditsPerMaxMsg));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				(" TxQueueDepth       : %d \n",
				 HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				("----------------------------------------------------\n"));
	}
}

A_BOOL htc_get_endpoint_statistics(HTC_HANDLE HTCHandle,
				   HTC_ENDPOINT_ID Endpoint,
				   HTC_ENDPOINT_STAT_ACTION Action,
				   HTC_ENDPOINT_STATS *pStats)
{
#ifdef HTC_EP_STAT_PROFILING
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	A_BOOL clearStats = false;
	A_BOOL sample = false;

	switch (Action) {
	case HTC_EP_STAT_SAMPLE:
		sample = true;
		break;
	case HTC_EP_STAT_SAMPLE_AND_CLEAR:
		sample = true;
		clearStats = true;
		break;
	case HTC_EP_STAT_CLEAR:
		clearStats = true;
		break;
	default:
		break;
	}

	A_ASSERT(Endpoint < ENDPOINT_MAX);

	/* lock out TX and RX while we sample and/or clear */
	LOCK_HTC_TX(target);
	LOCK_HTC_RX(target);

	if (sample) {
		A_ASSERT(pStats != NULL);
		/* return the stats to the caller */
		A_MEMCPY(pStats, &target->EndPoint[Endpoint].EndPointStats,
			 sizeof(HTC_ENDPOINT_STATS));
	}

	if (clearStats) {
		/* reset stats */
		A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats,
			  sizeof(HTC_ENDPOINT_STATS));
	}

	UNLOCK_HTC_RX(target);
	UNLOCK_HTC_TX(target);

	return true;
#else
	return false;
#endif
}

void *htc_get_targetdef(HTC_HANDLE htc_handle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	return hif_get_targetdef(target->hif_dev);
}

/**
 * htc_set_target_to_sleep() - set target to sleep
 * @context: ol_softc context
 *
 * Return: none
 */
void htc_set_target_to_sleep(void *context)
{
	struct ol_softc *scn = (struct ol_softc *)context;

	hif_set_target_sleep(scn, true, false);
}

/**
 * htc_cancel_deferred_target_sleep() - cancel deferred target sleep
 * @context: ol_softc context
 *
 * Return: none
 */
void htc_cancel_deferred_target_sleep(void *context)
{
	struct ol_softc *scn = (struct ol_softc *)context;
	hif_cancel_deferred_target_sleep(scn);
}

#ifdef IPA_OFFLOAD
void htc_ipa_get_ce_resource(HTC_HANDLE htc_handle,
			     uint32_t *ce_sr_base_paddr,
			     uint32_t *ce_sr_ring_size,
			     cdf_dma_addr_t *ce_reg_paddr)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	if (target->hif_dev != NULL) {
		hif_ipa_get_ce_resource(target->hif_dev,
					ce_sr_base_paddr,
					ce_sr_ring_size, ce_reg_paddr);
	}
}
#endif /* IPA_OFFLOAD */
