/*
 * Copyright (c) 2013-2017 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 */

#define MAX_HTC_RX_BUNDLE  2

#if defined(WLAN_DEBUG) || defined(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;
		}
		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);
		hif_mask_interrupt_call(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;
	}

	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);
	target->is_nodrop_pkt = false;
	target->wmi_ep_count = 1;

	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) {
				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;
}

static 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_epping_credit_allocation() - allocate credits/HTC buffers to WMI
 * @scn: pointer to hif_opaque_softc
 * @pEntry: pointer to tx credit allocation entry
 * @credits: number of credits
 *
 * Return: None
 */
static void
htc_setup_epping_credit_allocation(struct hif_opaque_softc *scn,
				   HTC_SERVICE_TX_CREDIT_ALLOCATION *pEntry,
				   int credits)
{
	switch (hif_get_bus_type(scn)) {
	case QDF_BUS_TYPE_PCI:
		pEntry++;
		pEntry->service_id = WMI_DATA_BE_SVC;
		pEntry->CreditAllocation = (credits >> 1);

		pEntry++;
		pEntry->service_id = WMI_DATA_BK_SVC;
		pEntry->CreditAllocation = (credits >> 1);
		break;
	case QDF_BUS_TYPE_SDIO:
		pEntry++;
		pEntry->service_id = WMI_DATA_BE_SVC;
		pEntry->CreditAllocation = credits;
		break;
	default:
		break;
	}
	return;
}

/**
 * htc_setup_target_buffer_assignments() - setup target buffer assignments
 * @target: HTC Target Pointer
 *
 * Return: A_STATUS
 */
static
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];

	status = A_OK;
	/*
	 * Allocate all credists/HTC buffers to WMI.
	 * no buffers are used/required for data. data always
	 * remains on host.
	 */
	if (HTC_IS_EPPING_ENABLED(target->con_mode)) {
		pEntry++;
		pEntry->service_id = WMI_CONTROL_SVC;
		pEntry->CreditAllocation = credits;
		/* 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.
		 */

		htc_setup_epping_credit_allocation(target->hif_dev,
						   pEntry, credits);
	} else {
		int i;
		uint32_t svc_id[] = {WMI_CONTROL_SVC, WMI_CONTROL_SVC_WMAC1,
						WMI_CONTROL_SVC_WMAC2};
		uint32_t max_wmi_svc = (sizeof(svc_id) / sizeof(uint32_t));

		if ((target->wmi_ep_count == 0) ||
				(target->wmi_ep_count > max_wmi_svc))
			return A_ERROR;

		/*
		 * Divide credit among number of endpoints for WMI
		 */
		credits = credits / target->wmi_ep_count;
		for (i = 0; i < target->wmi_ep_count; i++) {
			status = A_OK;
			pEntry++;
			pEntry->service_id = svc_id[i];
			pEntry->CreditAllocation = credits;
		}
	}

	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;
	uint8_t i = 0;
	HTC_PACKET *rx_bundle_packet, *temp_bundle_packet;

	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;
		}

		/* Allocate expected number of RX bundle buffer allocation */
		if (HTC_RX_BUNDLE_ENABLED(target)) {
			temp_bundle_packet = NULL;
			for (i = 0; i < MAX_HTC_RX_BUNDLE; i++) {
				rx_bundle_packet =
					allocate_htc_bundle_packet(target);
				if (rx_bundle_packet != NULL)
					rx_bundle_packet->ListLink.pNext =
						(DL_LIST *)temp_bundle_packet;
				else
					break;

				temp_bundle_packet = rx_bundle_packet;
			}
			target->pBundleFreeList = temp_bundle_packet;
		}

		/* 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);
	}
}

/**
 * htc_start() - Main HTC function to trigger HTC start
 * @HTCHandle: pointer to HTC handle
 *
 * Return: A_OK for success or an appropriate A_STATUS error
 */
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"));
		}

		if ((hif_get_bus_type(target->hif_dev) == QDF_BUS_TYPE_SDIO) ||
			(hif_get_bus_type(target->hif_dev) == QDF_BUS_TYPE_USB)) {
			if (HTC_RX_BUNDLE_ENABLED(target))
			pSetupComp->SetupFlags |=
				HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
			hif_set_bundle_mode(target->hif_dev, true,
				HTC_MAX_MSG_PER_BUNDLE_RX);
		}

		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 */

#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)

void htc_dump_bundle_stats(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	int total, i;

	total = 0;
	for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_RX; i++)
		total += target->rx_bundle_stats[i];

	if (total) {
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("RX Bundle stats:\n"));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("Total RX packets: %d\n",
						total));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (
				"Number of bundle: Number of packets\n"));
		for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_RX; i++)
			AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
					("%10d:%10d(%2d%s)\n", (i+1),
					 target->rx_bundle_stats[i],
					 ((target->rx_bundle_stats[i]*100)/
					  total), "%"));
	}


	total = 0;
	for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_TX; i++)
		total += target->tx_bundle_stats[i];

	if (total) {
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("TX Bundle stats:\n"));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("Total TX packets: %d\n",
						total));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				("Number of bundle: Number of packets\n"));
		for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_TX; i++)
			AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
					("%10d:%10d(%2d%s)\n", (i+1),
					 target->tx_bundle_stats[i],
					 ((target->tx_bundle_stats[i]*100)/
					  total), "%"));
	}
}

void htc_clear_bundle_stats(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);

	qdf_mem_zero(&target->rx_bundle_stats, sizeof(target->rx_bundle_stats));
	qdf_mem_zero(&target->tx_bundle_stats, sizeof(target->tx_bundle_stats));
}
#endif

/**
 * 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);
}

#ifdef FEATURE_RUNTIME_PM
int htc_pm_runtime_get(HTC_HANDLE htc_handle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	HTC_INFO("%s: %pS\n", __func__, (void *)_RET_IP_);
	return hif_pm_runtime_get(target->hif_dev);
}

int htc_pm_runtime_put(HTC_HANDLE htc_handle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	HTC_INFO("%s: %pS\n", __func__, (void *)_RET_IP_);
	return hif_pm_runtime_put(target->hif_dev);
}
#endif

/**
 * htc_set_wmi_endpoint_count: Set number of WMI endpoint
 * @htc_handle: HTC handle
 * @wmi_ep_count: WMI enpoint count
 *
 * return: None
 */
void htc_set_wmi_endpoint_count(HTC_HANDLE htc_handle, uint8_t wmi_ep_count)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	target->wmi_ep_count = wmi_ep_count;
}

/**
 * htc_get_wmi_endpoint_count: Get number of WMI endpoint
 * @htc_handle: HTC handle
 *
 * return: WMI enpoint count
 */
uint8_t htc_get_wmi_endpoint_count(HTC_HANDLE htc_handle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	return target->wmi_ep_count;
}
