/*
 * Copyright (c) 2013-2016 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 "htc_debug.h"
#include "htc_internal.h"
#include <hif.h>
#include <qdf_nbuf.h>           /* qdf_nbuf_t */
#include <qdf_types.h>          /* qdf_print */

#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)
{
	qdf_nbuf_t netbuf;
	netbuf = (qdf_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) {
		qdf_nbuf_free(netbuf);
	}

	qdf_mem_free(pPacket);
}

static HTC_PACKET *build_htc_tx_ctrl_packet(qdf_device_t osdev)
{
	HTC_PACKET *pPacket = NULL;
	qdf_nbuf_t netbuf;

	do {
		pPacket = (HTC_PACKET *) qdf_mem_malloc(sizeof(HTC_PACKET));
		if (NULL == pPacket) {
			break;
		}
		qdf_mem_zero(pPacket, sizeof(HTC_PACKET));
		netbuf = qdf_nbuf_alloc(osdev, HTC_CONTROL_BUFFER_SIZE,
					20, 4, true);
		if (NULL == netbuf) {
			qdf_mem_free(pPacket);
			pPacket = NULL;
			qdf_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;
	/* qdf_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;
		}
		qdf_mem_free(pPacket);
	}

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

		qdf_mem_free(pPacket);
	}
#endif

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

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

#ifdef FEATURE_RUNTIME_PM
/**
 * htc_runtime_pm_init(): runtime pm related intialization
 *
 * need to initialize a work item.
 */
static void htc_runtime_pm_init(HTC_TARGET *target)
{
	qdf_create_work(0, &target->queue_kicker, htc_kick_queues, target);
}

/**
 * htc_runtime_suspend() - runtime suspend HTC
 *
 * @htc_ctx: HTC context pointer
 *
 * This is a dummy function for symmetry.
 *
 * Return: 0 for success
 */
int htc_runtime_suspend(HTC_HANDLE htc_ctx)
{
	return 0;
}

/**
 * htc_runtime_resume(): resume htc
 *
 * The htc message queue needs to be kicked off after
 * a runtime resume.  Otherwise messages would get stuck.
 *
 * @htc_ctx: HTC context pointer
 *
 * Return: 0 for success;
 */
int htc_runtime_resume(HTC_HANDLE htc_ctx)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_ctx);

	if (target == NULL)
		return 0;

	qdf_sched_work(0, &target->queue_kicker);
	return 0;
}
#else
static inline void htc_runtime_pm_init(HTC_TARGET *target) { }
#endif

/* registered target arrival callback from the HIF layer */
HTC_HANDLE htc_create(void *ol_sc, HTC_INIT_INFO *pInfo, qdf_device_t osdev,
		      uint32_t con_mode)
{
	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 *) qdf_mem_malloc(sizeof(HTC_TARGET));
	if (target == NULL) {
		HTC_ERROR("%s: Unable to allocate memory", __func__);
		return NULL;
	}

	qdf_mem_zero(target, sizeof(HTC_TARGET));

	htc_runtime_pm_init(target);
	qdf_spinlock_create(&target->HTCLock);
	qdf_spinlock_create(&target->HTCRxLock);
	qdf_spinlock_create(&target->HTCTxLock);
	qdf_spinlock_create(&target->HTCCreditLock);

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

		reset_endpoint_states(target);

		INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);

		for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) {
			HTC_PACKET *pPacket =
				(HTC_PACKET *) qdf_mem_malloc(sizeof(HTC_PACKET));
			if (pPacket != NULL) {
				qdf_mem_zero(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 */
		qdf_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));
	hif_stop(htc_get_hif_device(HTCHandle));
	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->service_id = WMI_CONTROL_SVC;
	pEntry->CreditAllocation = credits;

	if (HTC_IS_EPPING_ENABLED(target->con_mode)) {
		/* 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, QDF, 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->service_id = WMI_DATA_BE_SVC;
		pEntry->CreditAllocation = (credits >> 1);

		pEntry++;
		pEntry->service_id = 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].service_id != 0) {
				AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
						("HTC Service Index : %d TX : 0x%2.2X : alloc:%d\n",
						 i,
						 target->ServiceTxAllocTable[i].
						 service_id,
						 target->ServiceTxAllocTable[i].
						 CreditAllocation));
			}
		}
	}

	return status;
}

uint8_t htc_get_credit_allocation(HTC_TARGET *target, uint16_t service_id)
{
	uint8_t allocation = 0;
	int i;

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

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

	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;
	uint16_t 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 =
			(uint8_t) 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 */
		qdf_mem_zero(&connect, sizeof(connect));
		qdf_mem_zero(&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.service_id = 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->service_id = 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 = (bool)htc_credit_flow;
		qdf_atomic_init(&pEndpoint->TxProcessCount);
	}
}

A_STATUS htc_start(HTC_HANDLE HTCHandle)
{
	qdf_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);
			qdf_print("%s: allocControlTxPacket failed\n",
				  __func__);
			status = A_NO_MEMORY;
			break;
		}

		netbuf =
		   (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket);
		/* assemble setup complete message */
		qdf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
		pSetupComp =
			(HTC_SETUP_COMPLETE_EX_MSG *) qdf_nbuf_data(netbuf);
		qdf_mem_zero(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,
				       (uint8_t *) 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
	qdf_nbuf_t netbuf;
	qdf_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 = qdf_nbuf_queue_remove(rx_sg_queue)) != NULL)
		qdf_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
	qdf_nbuf_t netbuf;
	qdf_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) {
			qdf_timer_stop(&pEndpoint->ul_poll_timer);
			qdf_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 = qdf_nbuf_queue_remove(rx_sg_queue)) != NULL)
		qdf_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->service_id)
			continue;

		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
			("--- EP : %d  service_id: 0x%X    --------------\n",
				 pEndpoint->Id, pEndpoint->service_id));
		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"));
	}
}

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);
	bool clearStats = false;
	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 */
		qdf_mem_copy(pStats, &target->endpoint[Endpoint].endpoint_stats,
			 sizeof(HTC_ENDPOINT_STATS));
	}

	if (clearStats) {
		/* reset stats */
		qdf_mem_zero(&target->endpoint[Endpoint].endpoint_stats,
			  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);
}

#ifdef IPA_OFFLOAD
/**
 * htc_ipa_get_ce_resource() - get uc resource on lower layer
 * @htc_handle: htc context
 * @ce_sr_base_paddr: copyengine source ring base physical address
 * @ce_sr_ring_size: copyengine source ring size
 * @ce_reg_paddr: copyengine register physical address
 *
 * Return: None
 */
void htc_ipa_get_ce_resource(HTC_HANDLE htc_handle,
			     qdf_dma_addr_t *ce_sr_base_paddr,
			     uint32_t *ce_sr_ring_size,
			     qdf_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 */

/**
 * htc_vote_link_down - API to vote for link down
 * @htc_handle: HTC handle
 *
 * API for upper layers to call HIF to vote for link down
 *
 * Return: void
 */
void htc_vote_link_down(HTC_HANDLE htc_handle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	if (!target->hif_dev)
		return;

	hif_vote_link_down(target->hif_dev);
}

/**
 * htc_vote_link_up - API to vote for link up
 * @htc_handle: HTC Handle
 *
 * API for upper layers to call HIF to vote for link up
 *
 * Return: void
 */
void htc_vote_link_up(HTC_HANDLE htc_handle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	if (!target->hif_dev)
		return;

	hif_vote_link_up(target->hif_dev);
}

/**
 * htc_can_suspend_link - API to query HIF for link status
 * @htc_handle: HTC Handle
 *
 * API for upper layers to call HIF to query if the link can suspend
 *
 * Return: void
 */
bool htc_can_suspend_link(HTC_HANDLE htc_handle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	if (!target->hif_dev)
		return false;

	return hif_can_suspend_link(target->hif_dev);
}
