/*
 * 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 <adf_nbuf.h> /* adf_nbuf_t */
#include <adf_os_mem.h> /* adf_os_mem_alloc */
#include <vos_getBin.h>
#include "epping_main.h"
#include "adf_trace.h"

#define HTC_DATA_RESOURCE_THRS 256
#define HTC_DATA_MINDESC_PERPACKET 2

typedef enum _HTC_SEND_QUEUE_RESULT {
    HTC_SEND_QUEUE_OK = 0,    /* packet was queued */
    HTC_SEND_QUEUE_DROP = 1,  /* this packet should be dropped */
} HTC_SEND_QUEUE_RESULT;

#ifndef DEBUG_CREDIT
#define DEBUG_CREDIT 0
#endif

#if DEBUG_CREDIT
/* bit mask to enable debug certain endpoint */
static unsigned ep_debug_mask = (1 << ENDPOINT_0) | (1 << ENDPOINT_1) | (1 << ENDPOINT_2);
#endif

/* HTC Control Path Credit History */
A_UINT32 g_htc_credit_history_idx = 0;
HTC_CREDIT_HISTORY htc_credit_history_buffer[HTC_CREDIT_HISTORY_MAX];

void htc_credit_record(htc_credit_exchange_type type, A_UINT32 tx_credit,
                       A_UINT32 htc_tx_queue_depth)
{
    if (HTC_CREDIT_HISTORY_MAX <= g_htc_credit_history_idx)
        g_htc_credit_history_idx = 0;

    htc_credit_history_buffer[g_htc_credit_history_idx].type = type;
    htc_credit_history_buffer[g_htc_credit_history_idx].time =
        adf_get_boottime();
    htc_credit_history_buffer[g_htc_credit_history_idx].tx_credit = tx_credit;
    htc_credit_history_buffer[g_htc_credit_history_idx].htc_tx_queue_depth =
        htc_tx_queue_depth;
    g_htc_credit_history_idx++;
}

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

    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                    ("\n%s: CE_send_cnt = %d, TX_comp_cnt = %d\n",
                     __func__, target->CE_send_cnt, target->TX_comp_cnt));
}

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

    if (!credits || !target) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: invalid args", __func__));
        return;
    }

    *credits = 0;
    LOCK_HTC_TX(target);
    for (i = 0; i < ENDPOINT_MAX; i++) {
        pEndpoint = &target->EndPoint[i];
        if (pEndpoint->ServiceID == WMI_CONTROL_SVC) {
            *credits = pEndpoint->TxCredits;
            break;
        }
    }
    UNLOCK_HTC_TX(target);
}

static INLINE void RestoreTxPacket(HTC_TARGET *target, HTC_PACKET *pPacket)
{
    if (pPacket->PktInfo.AsTx.Flags & HTC_TX_PACKET_FLAG_FIXUP_NETBUF) {
        adf_nbuf_t netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
        adf_nbuf_unmap(target->osdev, netbuf, ADF_OS_DMA_TO_DEVICE);
        adf_nbuf_pull_head(netbuf, sizeof(HTC_FRAME_HDR));
        pPacket->PktInfo.AsTx.Flags &= ~HTC_TX_PACKET_FLAG_FIXUP_NETBUF;
    }

}

static void DoSendCompletion(HTC_ENDPOINT       *pEndpoint,
                             HTC_PACKET_QUEUE   *pQueueToIndicate)
{
    do {

        if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
                /* nothing to indicate */
            break;
        }

        if (pEndpoint->EpCallBacks.EpTxCompleteMultiple != NULL) {
            AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d, send complete multiple callback (%d pkts) \n",
                     pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
                /* a multiple send complete handler is being used, pass the queue to the handler */
            pEndpoint->EpCallBacks.EpTxCompleteMultiple(pEndpoint->EpCallBacks.pContext,
                                                        pQueueToIndicate);
                /* all packets are now owned by the callback, reset queue to be safe */
            INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
        } else {
            HTC_PACKET *pPacket;
            /* using legacy EpTxComplete */
            do {
                pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
                AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d send complete callback on packet %pK \n",
                        pEndpoint->Id, pPacket));
                pEndpoint->EpCallBacks.EpTxComplete(pEndpoint->EpCallBacks.pContext, pPacket);
            } while (!HTC_QUEUE_EMPTY(pQueueToIndicate));
        }

    } while (FALSE);

}

static void SendPacketCompletion(HTC_TARGET *target, HTC_PACKET *pPacket)
{
    HTC_ENDPOINT    *pEndpoint = &target->EndPoint[pPacket->Endpoint];
    HTC_PACKET_QUEUE container;

    RestoreTxPacket(target, pPacket);
    INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);

    /* do completion */
    DoSendCompletion(pEndpoint,&container);
}

void
HTCSendCompleteCheckCleanup(void *context)
{
    HTC_ENDPOINT *pEndpoint = (HTC_ENDPOINT *) context;
    HTCSendCompleteCheck(pEndpoint, 1);
}


HTC_PACKET *AllocateHTCBundleTxPacket(HTC_TARGET *target)
{
    HTC_PACKET *pPacket;
    HTC_PACKET_QUEUE *pQueueSave;
    adf_nbuf_t netbuf;

    LOCK_HTC_TX(target);
    if (NULL == target->pBundleFreeTxList) {
        UNLOCK_HTC_TX(target);

        /* for HTT packets, if AltDataCreditSize is non zero, we will have
         allocated more space per packet (i.e., TargetCreditSize-AltDataCreditSize)
         per bundle packet, but this should is required since we reuse the packet
         for all services and all endpoints */

        netbuf = adf_nbuf_alloc(NULL,
                HTC_MAX_MSG_PER_BUNDLE_TX * target->TargetCreditSize,
                0,
                4,
                FALSE);
        AR_DEBUG_ASSERT(netbuf);
        if (!netbuf)
        {
            return NULL;
        }
        pPacket = adf_os_mem_alloc(NULL, sizeof(HTC_PACKET));
        AR_DEBUG_ASSERT(pPacket);
        if (!pPacket)
        {
            adf_nbuf_free(netbuf);
            return NULL;
        }
        pQueueSave = adf_os_mem_alloc(NULL, sizeof(HTC_PACKET_QUEUE));
        AR_DEBUG_ASSERT(pQueueSave);
        if (!pQueueSave)
        {
            adf_nbuf_free(netbuf);
            adf_os_mem_free(pPacket);
            return NULL;
        }
        INIT_HTC_PACKET_QUEUE(pQueueSave);
        pPacket->pContext = pQueueSave;
        SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf);
        pPacket->pBuffer = adf_nbuf_data(netbuf);
        pPacket->BufferLength = adf_nbuf_len(netbuf);

        //store the original head room so that we can restore this when we "free" the packet
        //free packet puts the packet back on the free list
        pPacket->netbufOrigHeadRoom = adf_nbuf_headroom(netbuf);
        return pPacket;
    }

    //already done malloc - restore from free list
    pPacket = target->pBundleFreeTxList;
    AR_DEBUG_ASSERT(pPacket);
    if (!pPacket)
    {
        UNLOCK_HTC_TX(target);
        return NULL;
    }
    target->pBundleFreeTxList = (HTC_PACKET *)pPacket->ListLink.pNext;
    UNLOCK_HTC_TX(target);
    pPacket->ListLink.pNext = NULL;

    return pPacket;
}

void FreeHTCBundleTxPacket(HTC_TARGET *target, HTC_PACKET *pPacket)
{
    A_UINT32 curentHeadRoom;
    adf_nbuf_t netbuf;
    HTC_PACKET_QUEUE *pQueueSave;

    netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
    AR_DEBUG_ASSERT(netbuf);
    if (!netbuf)
    {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("\n%s: Invalid netbuf in HTC "
                                        "Packet\n", __func__));
        return;
    }

    // HIF adds data to the headroom section of the nbuf, restore the original
    // size. If this is not done, headroom keeps shrinking with every HIF send
    // and eventually HIF ends up doing another malloc big enough to store the
    // data + its header

    curentHeadRoom = adf_nbuf_headroom(netbuf);
    adf_nbuf_pull_head(netbuf, pPacket->netbufOrigHeadRoom - curentHeadRoom);
    adf_nbuf_trim_tail(netbuf, adf_nbuf_len(netbuf));

    //restore the pBuffer pointer. HIF changes this
    pPacket->pBuffer = adf_nbuf_data(netbuf);
    pPacket->BufferLength = adf_nbuf_len(netbuf);

    //restore queue
    pQueueSave = (HTC_PACKET_QUEUE*)pPacket->pContext;
    AR_DEBUG_ASSERT(pQueueSave);

    INIT_HTC_PACKET_QUEUE(pQueueSave);

    LOCK_HTC_TX(target);
    if (target->pBundleFreeTxList == NULL) {
        target->pBundleFreeTxList = pPacket;
        pPacket->ListLink.pNext = NULL;
    } else {
        pPacket->ListLink.pNext = (DL_LIST *)target->pBundleFreeTxList;
        target->pBundleFreeTxList = pPacket;
    }
    UNLOCK_HTC_TX(target);
}

HTC_PACKET *AllocateHTCBundleRxPacket(HTC_TARGET *target)
{
    HTC_PACKET *pPacket;
    HTC_PACKET_QUEUE *pQueueSave;
    adf_nbuf_t netbuf;
    LOCK_HTC_TX(target);
    if (NULL == target->pBundleFreeRxList) {
        UNLOCK_HTC_TX(target);
        netbuf = adf_nbuf_alloc(NULL,
                HTC_MAX_MSG_PER_BUNDLE_RX * target->TargetCreditSize,
                0,
                4,
                FALSE);
        AR_DEBUG_ASSERT(netbuf);
        if (!netbuf)
        {
            return NULL;
        }
        pPacket = adf_os_mem_alloc(NULL, sizeof(HTC_PACKET));
        AR_DEBUG_ASSERT(pPacket);
        if (!pPacket)
        {
            adf_nbuf_free(netbuf);
            return NULL;
        }
        pQueueSave = adf_os_mem_alloc(NULL, sizeof(HTC_PACKET_QUEUE));
        AR_DEBUG_ASSERT(pQueueSave);
        if (!pQueueSave)
        {
            adf_nbuf_free(netbuf);
            adf_os_mem_free(pPacket);
            return NULL;
        }
        INIT_HTC_PACKET_QUEUE(pQueueSave);
        pPacket->pContext = pQueueSave;
        SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf);
        pPacket->pBuffer = adf_nbuf_data(netbuf);
        pPacket->BufferLength = adf_nbuf_len(netbuf);

        //store the original head room so that we can restore this when we "free" the packet
        //free packet puts the packet back on the free list
        pPacket->netbufOrigHeadRoom = adf_nbuf_headroom(netbuf);
        return pPacket;
    }

    //already done malloc - restore from free list
    pPacket = target->pBundleFreeRxList;
    AR_DEBUG_ASSERT(pPacket);
    if (!pPacket)
    {
        UNLOCK_HTC_TX(target);
        return NULL;
    }
    target->pBundleFreeRxList = (HTC_PACKET *)pPacket->ListLink.pNext;
    UNLOCK_HTC_TX(target);
    pPacket->ListLink.pNext = NULL;

    return pPacket;
}

void FreeHTCBundleRxPacket(HTC_TARGET *target, HTC_PACKET *pPacket)
{
    A_UINT32 curentHeadRoom;
    adf_nbuf_t netbuf;
    HTC_PACKET_QUEUE *pQueueSave;

    netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
    AR_DEBUG_ASSERT(netbuf);
    if (!netbuf)
    {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("\n%s: Invalid netbuf in HTC "
                                        "Packet\n", __func__));
        return;
    }

    // HIF adds data to the headroom section of the nbuf, restore the original
    // size. If this is not done, headroom keeps shrinking with every HIF send
    // and eventually HIF ends up doing another malloc big enough to store the
    // data + its header

    curentHeadRoom = adf_nbuf_headroom(netbuf);
    adf_nbuf_pull_head(netbuf, pPacket->netbufOrigHeadRoom - curentHeadRoom);
    adf_nbuf_trim_tail(netbuf, adf_nbuf_len(netbuf));

    //restore the pBuffer pointer. HIF changes this
    pPacket->pBuffer = adf_nbuf_data(netbuf);
    pPacket->BufferLength = adf_nbuf_len(netbuf);

    //restore queue
    pQueueSave = (HTC_PACKET_QUEUE*)pPacket->pContext;
    AR_DEBUG_ASSERT(pQueueSave);

    INIT_HTC_PACKET_QUEUE(pQueueSave);

    LOCK_HTC_TX(target);
    if (target->pBundleFreeRxList == NULL) {
        target->pBundleFreeRxList = pPacket;
        pPacket->ListLink.pNext = NULL;
    } else {
        pPacket->ListLink.pNext = (DL_LIST *)target->pBundleFreeRxList;
        target->pBundleFreeRxList = pPacket;
    }
    UNLOCK_HTC_TX(target);
}


#if defined(HIF_USB) || defined(HIF_SDIO)
#ifdef ENABLE_BUNDLE_TX
static A_STATUS HTCSendBundledNetbuf(HTC_TARGET *target,
        HTC_ENDPOINT *pEndpoint,
        unsigned char *pBundleBuffer,
        HTC_PACKET *pPacketTx)
{
    adf_os_size_t data_len;
    A_STATUS status;
    adf_nbuf_t bundleBuf;
    bundleBuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacketTx);
    data_len = pBundleBuffer - adf_nbuf_data(bundleBuf);
    adf_nbuf_put_tail(bundleBuf, data_len);
    SET_HTC_PACKET_INFO_TX(pPacketTx,
            target,
            pBundleBuffer,
            data_len,
            pEndpoint->Id,
            HTC_TX_PACKET_TAG_BUNDLED);
    LOCK_HTC_TX(target);
    HTC_PACKET_ENQUEUE(&pEndpoint->TxLookupQueue, pPacketTx);
    pEndpoint->ul_outstanding_cnt++;
    UNLOCK_HTC_TX(target);
#if DEBUG_BUNDLE
    adf_os_print(" Send bundle EP%d buffer size:0x%x, total:0x%x, count:%d.\n",
            pEndpoint->Id,
            pEndpoint->TxCreditSize,
            data_len,
            data_len / pEndpoint->TxCreditSize);
#endif

#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
    if ((data_len / pEndpoint->TxCreditSize) <= HTC_MAX_MSG_PER_BUNDLE_TX) {
        target->tx_bundle_stats[(data_len / pEndpoint->TxCreditSize) - 1]++;
    }
#endif

    status = HIFSend_head(target->hif_dev,
               pEndpoint->UL_PipeID,
               pEndpoint->Id,
               data_len,
               bundleBuf);
    if (status != A_OK){
        adf_os_print("%s:HIFSend_head failed(len=%zu).\n", __FUNCTION__,
                data_len);
        LOCK_HTC_TX(target);
        HTC_PACKET_REMOVE(&pEndpoint->TxLookupQueue, pPacketTx);
        UNLOCK_HTC_TX(target);
    }
    return status;
}

static A_STATUS HTCIssuePacketsBundle(HTC_TARGET *target,
                                      HTC_ENDPOINT *pEndpoint,
                                      HTC_PACKET_QUEUE *pPktQueue)
{
   int              i, frag_count, nbytes;
   adf_nbuf_t       netbuf, bundleBuf;
   unsigned char    *pBundleBuffer = NULL;
   HTC_PACKET       *pPacket = NULL, *pPacketTx = NULL;
#ifndef HIF_USB
   HTC_FRAME_HDR    *pHtcHdr;
#endif
   int              last_creditPad = 0;
   int              creditPad, creditRemainder,transferLength, bundlesSpaceRemaining = 0;
   HTC_PACKET_QUEUE *pQueueSave = NULL;
   A_STATUS ret;

   bundlesSpaceRemaining = HTC_MAX_MSG_PER_BUNDLE_TX * pEndpoint->TxCreditSize;

   pPacketTx = AllocateHTCBundleTxPacket(target);
   if (!pPacketTx)
   {
       //good time to panic
       AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AllocateHTCBundleTxPacket failed \n"));
       AR_DEBUG_ASSERT(FALSE);
       ret = A_NO_MEMORY;
       goto failed1;
   }
   bundleBuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacketTx);
   pBundleBuffer = adf_nbuf_data(bundleBuf);
   pQueueSave = (HTC_PACKET_QUEUE*)pPacketTx->pContext;
   while (1) {
       pPacket = HTC_PACKET_DEQUEUE(pPktQueue);
       if (pPacket == NULL){
           break;
       }
       creditPad = 0;
       transferLength = pPacket->ActualLength + HTC_HDR_LENGTH;
       creditRemainder = transferLength % pEndpoint->TxCreditSize;
       if(creditRemainder != 0){
            if(transferLength < pEndpoint->TxCreditSize){
                creditPad = pEndpoint->TxCreditSize - transferLength;
            } else {
                creditPad = creditRemainder;
            }
            transferLength += creditPad;
       }

       if (bundlesSpaceRemaining < transferLength){
           /* send out previous buffer */
           if (A_OK != HTCSendBundledNetbuf(target, pEndpoint,
                                pBundleBuffer - last_creditPad, pPacketTx)) {
               ret = A_EBUSY;
               HTC_PACKET_ENQUEUE(pQueueSave, pPacket);
               goto failed2;
           }

           /* One packet has been dequeued from sending queue when enter
            * this loop, so need to add 1 back for this checking.
            */
           if ((HTC_PACKET_QUEUE_DEPTH(pPktQueue) + 1) < HTC_MIN_MSG_PER_BUNDLE){
               HTC_PACKET_ENQUEUE_TO_HEAD(pPktQueue, pPacket);
               goto success;
           }
           bundlesSpaceRemaining = HTC_MAX_MSG_PER_BUNDLE_TX * pEndpoint->TxCreditSize;
           pPacketTx = AllocateHTCBundleTxPacket(target);
           if (!pPacketTx)
           {
               HTC_PACKET_ENQUEUE_TO_HEAD(pPktQueue, pPacket);
               //good time to panic
               AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AllocateHTCBundleTxPacket failed \n"));
               AR_DEBUG_ASSERT(FALSE);
               ret = A_NO_MEMORY;
               goto failed1;
           }
           bundleBuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacketTx);
           pBundleBuffer = adf_nbuf_data(bundleBuf);
           pQueueSave = (HTC_PACKET_QUEUE*)pPacketTx->pContext;
       }

       bundlesSpaceRemaining -= transferLength;
       netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
#ifndef HIF_USB
       pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0);
       HTC_WRITE32(pHtcHdr, SM(pPacket->ActualLength, HTC_FRAME_HDR_PAYLOADLEN) |
               SM(pPacket->PktInfo.AsTx.SendFlags | HTC_FLAGS_SEND_BUNDLE, HTC_FRAME_HDR_FLAGS) |
               SM(pPacket->Endpoint, HTC_FRAME_HDR_ENDPOINTID));
       HTC_WRITE32((A_UINT32 *)pHtcHdr + 1,
                 SM(pPacket->PktInfo.AsTx.SeqNo, HTC_FRAME_HDR_CONTROLBYTES1) |
                 SM(creditPad, HTC_FRAME_HDR_RESERVED));
       pHtcHdr->reserved = creditPad;
#endif
       frag_count = adf_nbuf_get_num_frags(netbuf);
       nbytes = pPacket->ActualLength + HTC_HDR_LENGTH;
       for (i = 0; i < frag_count && nbytes > 0; i ++){
           int frag_len = adf_nbuf_get_frag_len(netbuf, i);
           unsigned char *frag_addr = adf_nbuf_get_frag_vaddr(netbuf, i);
           if (frag_len > nbytes){
               frag_len = nbytes;
           }
           A_MEMCPY(pBundleBuffer, frag_addr, frag_len);
           nbytes -= frag_len;
           pBundleBuffer += frag_len;
       }
       HTC_PACKET_ENQUEUE(pQueueSave, pPacket);
       pBundleBuffer += creditPad;

#ifdef HIF_USB
       /* last one can't be packed. */
       last_creditPad = creditPad;
#endif
   }
   if (pBundleBuffer != adf_nbuf_data(bundleBuf)){
       /* send out remaining buffer */
       if (A_OK != HTCSendBundledNetbuf(target, pEndpoint,
                            pBundleBuffer - last_creditPad, pPacketTx))
       {
           ret = A_EBUSY;
           goto failed2;
       }
   } else {
       FreeHTCBundleTxPacket(target, pPacketTx);
   }

success:
   return A_OK;

failed2:
    if (!HTC_QUEUE_EMPTY(pQueueSave))
       HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(pPktQueue, pQueueSave);
    FreeHTCBundleTxPacket(target, pPacketTx);
failed1:
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                    ("send bundle buffer failed(%d) \n", ret));
    return ret;
}
#endif /* ENABLE_BUNDLE_TX */
#endif

static A_STATUS HTCIssuePackets(HTC_TARGET       *target,
                                HTC_ENDPOINT     *pEndpoint,
                                HTC_PACKET_QUEUE *pPktQueue)
{
    A_STATUS            status = A_OK;
    adf_nbuf_t          netbuf;
    HTC_PACKET          *pPacket = NULL;
    u_int16_t           payloadLen;
    HTC_FRAME_HDR       *pHtcHdr;
    bool                is_tx_runtime_put = false;

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCIssuePackets: Queue: %pK, Pkts %d \n",
                    pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue)));
    while (TRUE) {
#if defined(HIF_USB) || defined(HIF_SDIO)
#ifdef ENABLE_BUNDLE_TX
        if(
#ifndef HIF_USB
           IS_TX_CREDIT_FLOW_ENABLED(pEndpoint) &&
#endif
                HTC_ENABLE_BUNDLE(target) &&
                HTC_PACKET_QUEUE_DEPTH(pPktQueue) >= HTC_MIN_MSG_PER_BUNDLE){
            HTCIssuePacketsBundle(target, pEndpoint, pPktQueue);
        }
#endif
#endif
        /* if not bundling or there was a packet that could not be placed in a bundle,
         * and send it by normal way
         */
        pPacket = HTC_PACKET_DEQUEUE(pPktQueue);
        if(NULL == pPacket){
            /* local queue is fully drained */
            break;
        }

        netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
        AR_DEBUG_ASSERT(netbuf);
        /* Non-credit enabled endpoints have been mapped and setup by now,
         * so no need to revisit the HTC headers
         */
        if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) {

            payloadLen = pPacket->ActualLength;
            /* setup HTC frame header */

            pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0);
            AR_DEBUG_ASSERT(pHtcHdr);


            HTC_WRITE32(pHtcHdr, SM(payloadLen, HTC_FRAME_HDR_PAYLOADLEN) |
                    SM(pPacket->PktInfo.AsTx.SendFlags, HTC_FRAME_HDR_FLAGS) |
                    SM(pPacket->Endpoint, HTC_FRAME_HDR_ENDPOINTID));
            HTC_WRITE32(((A_UINT32 *)pHtcHdr) + 1,
                    SM(pPacket->PktInfo.AsTx.SeqNo, HTC_FRAME_HDR_CONTROLBYTES1));

            /*
             * Now that the HTC frame header has been added, the netbuf can be
             * mapped.  This only applies to non-data frames, since data frames
             * were already mapped as they entered into the driver.
             * Check the "FIXUP_NETBUF" flag to see whether this is a data netbuf
             * that is already mapped, or a non-data netbuf that needs to be
             * mapped.
             */
            if (pPacket->PktInfo.AsTx.Flags & HTC_TX_PACKET_FLAG_FIXUP_NETBUF) {
                adf_nbuf_map(
                        target->osdev,
                        GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket),
                        ADF_OS_DMA_TO_DEVICE);
            }
        }
        LOCK_HTC_TX(target);
            /* store in look up queue to match completions */
#ifdef ATH_11AC_TXCOMPACT
        if (HTT_DATA_MSG_SVC != pEndpoint->ServiceID)
#endif /* ATH_11AC_TXCOMPACT */
        {
            HTC_PACKET_ENQUEUE(&pEndpoint->TxLookupQueue,pPacket);
        }
        INC_HTC_EP_STAT(pEndpoint,TxIssued,1);
        pEndpoint->ul_outstanding_cnt++;
        UNLOCK_HTC_TX(target);

        if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_RUNTIME_PUT)
            is_tx_runtime_put = true;

        status = HIFSend_head(target->hif_dev,
                              pEndpoint->UL_PipeID, pEndpoint->Id,
                              HTC_HDR_LENGTH + pPacket->ActualLength,
                              netbuf);
#if DEBUG_BUNDLE
        adf_os_print(" Send single EP%d buffer size:0x%x, total:0x%x.\n",
            pEndpoint->Id,
            pEndpoint->TxCreditSize,
            HTC_HDR_LENGTH + pPacket->ActualLength);
#endif

#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
        target->tx_bundle_stats[0]++;
#endif

	target->CE_send_cnt++;

        if (adf_os_unlikely(A_FAILED(status))) {
            /* TODO : if more than 1 endpoint maps to the same PipeID it is possible
             * to run out of resources in the HIF layer. Don't emit the error */
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HIFSend Failed status: %d\n", status));
            LOCK_HTC_TX(target);
	    target->CE_send_cnt--;
            pEndpoint->ul_outstanding_cnt--;
            HTC_PACKET_REMOVE(&pEndpoint->TxLookupQueue,pPacket);
                /* reclaim credits */
            pEndpoint->TxCredits += pPacket->PktInfo.AsTx.CreditsUsed;
                /* put it back into the callers queue */
            HTC_PACKET_ENQUEUE_TO_HEAD(pPktQueue,pPacket);
            UNLOCK_HTC_TX(target);
            break;
        }

        /*
         * For HTT messages the Tx complete is disabled and for some HTT
         * messages which doesn't have response from FW, runtime pm put
         * is not happening. To address that the HTT packet which is tagged
         * with HTC_TX_PACKET_TAG_RUNTIME_PUT releases the count after the
         * packet sent is successful
         */
        if (is_tx_runtime_put) {
            is_tx_runtime_put = false;
            hif_pm_runtime_put(target->hif_dev);
        }
    }

    if (adf_os_unlikely(A_FAILED(status)))
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
            ("htc_issue_packets, failed pkt:0x%pK status:%d",
            pPacket, status));

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCIssuePackets \n"));

    return status;
}

#ifdef FEATURE_RUNTIME_PM
static void GetHTCAutoPmSendPackets(HTC_TARGET        *target,
                                    HTC_ENDPOINT      *pEndpoint,
                                    HTC_PACKET_QUEUE  *pQueue)
{
	HTC_PACKET   *pPacket;
	/*
	 * If the EP is not WMI EP then it is not required to go through
	 * the queue to find the tagged packkets.
	 */
	if (pEndpoint->ServiceID != WMI_CONTROL_SVC)
		return;

	ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue.QueueHead, pPacket,
			HTC_PACKET, ListLink) {

		if (pPacket->PktInfo.AsTx.Tag != HTC_TX_PACKET_TAG_AUTO_PM)
			continue;

		HTC_PACKET_REMOVE(&pEndpoint->TxQueue, pPacket);
		HTC_PACKET_ENQUEUE(pQueue, pPacket);
	} ITERATE_END
}

static void RequeueHTCAutoPmSendPackets(HTC_TARGET        *target,
                                        HTC_ENDPOINT      *pEndpoint,
                                        HTC_PACKET_QUEUE  *pQueue)
{
	if (pEndpoint->ServiceID != WMI_CONTROL_SVC)
		return;

	/*
	 * Go through remaining packets in the temporary queue and add them to
	 * head of the queue so that those would be sent at priority than other
	 * packets
	 */
	HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&pEndpoint->TxQueue, pQueue);
}
#else
static inline void GetHTCAutoPmSendPackets(HTC_TARGET        *target,
                                           HTC_ENDPOINT      *pEndpoint,
                                           HTC_PACKET_QUEUE  *pQueue)
{
	return;
}
static inline void RequeueHTCAutoPmSendPackets(HTC_TARGET        *target,
                                               HTC_ENDPOINT      *pEndpoint,
                                               HTC_PACKET_QUEUE  *pQueue)
{
	return;
}
#endif

    /* get HTC send packets from the TX queue on an endpoint, based on available credits */
void GetHTCSendPacketsCreditBased(HTC_TARGET        *target,
                                  HTC_ENDPOINT      *pEndpoint,
                                  HTC_PACKET_QUEUE  *pQueue)
{
    int          creditsRequired;
    int          remainder;
    A_UINT8      sendFlags;
    HTC_PACKET   *pPacket;
    unsigned int transferLength;
    HTC_PACKET_QUEUE *pTxQueue;
    HTC_PACKET_QUEUE tempQueue;
    A_BOOL AutoPMQueue = FALSE;

    /****** NOTE : the TX lock is held when this function is called *****************/
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPacketsCreditBased \n"));

    INIT_HTC_PACKET_QUEUE(&tempQueue);

    GetHTCAutoPmSendPackets(target, pEndpoint, &tempQueue);

    if (!HTC_QUEUE_EMPTY(&tempQueue)) {
        pTxQueue = &tempQueue;
        AutoPMQueue = TRUE;
    } else
        pTxQueue = &pEndpoint->TxQueue;

        /* loop until we can grab as many packets out of the queue as we can */
    while (TRUE) {

        sendFlags = 0;

        if (!AutoPMQueue && hif_pm_runtime_get(target->hif_dev)) {
           A_ASSERT(HTC_PACKET_QUEUE_DEPTH(pQueue) == 0);
           break;
        }

        /* get packet at head, but don't remove it */
        pPacket = HTC_GET_PKT_AT_HEAD(pTxQueue);
        if (pPacket == NULL) {
            if (!AutoPMQueue)
                hif_pm_runtime_put(target->hif_dev);
            break;
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got head packet:%pK , Queue Depth: %d\n",
                pPacket, HTC_PACKET_QUEUE_DEPTH(pTxQueue)));

        transferLength = pPacket->ActualLength + HTC_HDR_LENGTH;

        if (transferLength <= pEndpoint->TxCreditSize) {
            creditsRequired = 1;
        } else {
                /* figure out how many credits this message requires */
            creditsRequired = transferLength / pEndpoint->TxCreditSize;
            remainder = transferLength % pEndpoint->TxCreditSize;

            if (remainder) {
                creditsRequired++;
            }
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Credits Required:%d   Got:%d\n",
                            creditsRequired, pEndpoint->TxCredits));

        if (pEndpoint->Id == ENDPOINT_0) {
            /* endpoint 0 is special, it always has a credit and does not require credit based
             * flow control */
            creditsRequired = 0;
        } else {

            if (pEndpoint->TxCredits < creditsRequired) {
#if DEBUG_CREDIT
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" EP%d, No Credit now. %d < %d\n",
                        pEndpoint->Id, pEndpoint->TxCredits, creditsRequired));
#endif
                if (!AutoPMQueue)
                   hif_pm_runtime_put(target->hif_dev);
                break;
            }

            pEndpoint->TxCredits -= creditsRequired;
            INC_HTC_EP_STAT(pEndpoint, TxCreditsConsummed, creditsRequired);

                /* check if we need credits back from the target */
            if (pEndpoint->TxCredits <= pEndpoint->TxCreditsPerMaxMsg) {
                /* tell the target we need credits ASAP! */
                sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE;

                if (pEndpoint->ServiceID == WMI_CONTROL_SVC) {
                    LOCK_HTC_CREDIT(target);
                    htc_credit_record(HTC_REQUEST_CREDIT, pEndpoint->TxCredits,
                        HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue));
                    UNLOCK_HTC_CREDIT(target);
                }

                INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1);
#if DEBUG_CREDIT
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" EP%d Needs Credits\n", pEndpoint->Id));
#endif
            }
        }

            /* now we can fully dequeue */
        pPacket = HTC_PACKET_DEQUEUE(pTxQueue);
	if (pPacket) {
		/* save the number of credits this packet consumed */
		pPacket->PktInfo.AsTx.CreditsUsed = creditsRequired;
		/* save send flags */
		pPacket->PktInfo.AsTx.SendFlags = sendFlags;

		/* queue this packet into the caller's queue */
		HTC_PACKET_ENQUEUE(pQueue,pPacket);
	}
    }

    if (AutoPMQueue)
        RequeueHTCAutoPmSendPackets(target, pEndpoint, &tempQueue);

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-GetHTCSendPacketsCreditBased \n"));
}

void GetHTCSendPackets(HTC_TARGET        *target,
                       HTC_ENDPOINT      *pEndpoint,
                       HTC_PACKET_QUEUE  *pQueue,
                       int                Resources)
{

    HTC_PACKET   *pPacket;
    HTC_PACKET_QUEUE *pTxQueue;
    HTC_PACKET_QUEUE tempQueue;
    A_BOOL AutoPMQueue = FALSE;

    /****** NOTE : the TX lock is held when this function is called *****************/
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPackets %d resources\n",Resources));

    INIT_HTC_PACKET_QUEUE(&tempQueue);

    GetHTCAutoPmSendPackets(target, pEndpoint, &tempQueue);

    if (!HTC_QUEUE_EMPTY(&tempQueue)) {
        pTxQueue = &tempQueue;
        AutoPMQueue = TRUE;
    } else
        pTxQueue = &pEndpoint->TxQueue;
        /* loop until we can grab as many packets out of the queue as we can */
    while (Resources > 0) {
        int num_frags;

        if (!AutoPMQueue && hif_pm_runtime_get(target->hif_dev)) {
           A_ASSERT(HTC_PACKET_QUEUE_DEPTH(pQueue) == 0);
           break;
        }

        pPacket = HTC_PACKET_DEQUEUE(pTxQueue);
        if (pPacket == NULL) {
            if (!AutoPMQueue)
               hif_pm_runtime_put(target->hif_dev);
            break;
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got packet:%pK , New Queue Depth: %d\n",
                pPacket, HTC_PACKET_QUEUE_DEPTH(pTxQueue)));
        /* For non-credit path the sequence number is already embedded
         * in the constructed HTC header
         */
#if 0
        pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo;
        pEndpoint->SeqNo++;
#endif
        pPacket->PktInfo.AsTx.SendFlags = 0;
        pPacket->PktInfo.AsTx.CreditsUsed = 0;
        /* queue this packet into the caller's queue */
        HTC_PACKET_ENQUEUE(pQueue,pPacket);

        /*
         * FIX THIS:
         * For now, avoid calling adf_nbuf_get_num_frags before calling
         * adf_nbuf_map, because the MacOS version of adf_nbuf_t doesn't
         * support adf_nbuf_get_num_frags until after adf_nbuf_map has
         * been done.
         * Assume that the non-data netbufs, i.e. the WMI message netbufs,
         * consist of a single fragment.
         */
        num_frags =
            (pPacket->PktInfo.AsTx.Flags & HTC_TX_PACKET_FLAG_FIXUP_NETBUF) ?
            1 /* WMI messages are in a single-fragment network buffer */ :
            adf_nbuf_get_num_frags(GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket));
        Resources -= num_frags;
    }

    if (AutoPMQueue)
        RequeueHTCAutoPmSendPackets(target, pEndpoint, &tempQueue);

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-GetHTCSendPackets \n"));

}

static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET       *target,
                                        HTC_ENDPOINT     *pEndpoint,
                                        HTC_PACKET_QUEUE *pCallersSendQueue)
{
    HTC_PACKET_QUEUE      sendQueue; /* temp queue to hold packets at various stages */
    HTC_PACKET            *pPacket;
    int                   tx_resources;
    int                   overflow;
    HTC_SEND_QUEUE_RESULT result = HTC_SEND_QUEUE_OK;

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (Queue:%pK Depth:%d)\n",
            pCallersSendQueue,
            (pCallersSendQueue == NULL) ? 0 : HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue)));

        /* init the local send queue */
    INIT_HTC_PACKET_QUEUE(&sendQueue);

    do {

        if (NULL == pCallersSendQueue) {
                /* caller didn't provide a queue, just wants us to check queues and send */
            break;
        }

        if (HTC_QUEUE_EMPTY(pCallersSendQueue)) {
                /* empty queue */
            OL_ATH_HTC_PKT_ERROR_COUNT_INCR(target,HTC_PKT_Q_EMPTY);
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Empty queue\n"));
            result = HTC_SEND_QUEUE_DROP;
            break;
        }

        if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) >= pEndpoint->MaxTxQueueDepth) {
                    /* we've already overflowed */
            overflow = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue);
        } else {
                /* figure out how much we will overflow by */
            overflow = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
            overflow += HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue);
                /* figure out how much we will overflow the TX queue by */
            overflow -= pEndpoint->MaxTxQueueDepth;
        }

            /* if overflow is negative or zero, we are okay */
        if (overflow > 0) {
            AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
                (" Endpoint %d, TX queue will overflow :%d , Tx Depth:%d, Max:%d \n",
                pEndpoint->Id, overflow, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue), pEndpoint->MaxTxQueueDepth));
        }
        if ((overflow <= 0) || (pEndpoint->EpCallBacks.EpSendFull == NULL)) {
                /* all packets will fit or caller did not provide send full indication handler
                 * --  just move all of them to the local sendQueue object */
		HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&sendQueue, pCallersSendQueue);
        } else {
            int               i;
            int               goodPkts = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue) - overflow;

            A_ASSERT(goodPkts >= 0);
                /* we have overflowed, and a callback is provided */
                /* dequeue all non-overflow packets into the sendqueue */
            for (i = 0; i < goodPkts; i++) {
                    /* pop off caller's queue*/
                pPacket = HTC_PACKET_DEQUEUE(pCallersSendQueue);
                A_ASSERT(pPacket != NULL);
                    /* insert into local queue */
                HTC_PACKET_ENQUEUE(&sendQueue,pPacket);
            }

                /* the caller's queue has all the packets that won't fit*/
                /* walk through the caller's queue and indicate each one to the send full handler */
            ITERATE_OVER_LIST_ALLOW_REMOVE(&pCallersSendQueue->QueueHead, pPacket, HTC_PACKET, ListLink) {

                AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Indicating overflowed TX packet: %pK \n",
                                pPacket));
                /*
                 * Remove headroom reserved for HTC_FRAME_HDR before giving
                 * the packet back to the user via the EpSendFull callback.
                 */
                RestoreTxPacket(target, pPacket);

                if (pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext,
                                                      pPacket) == HTC_SEND_FULL_DROP) {
                        /* callback wants the packet dropped */
                    INC_HTC_EP_STAT(pEndpoint, TxDropped, 1);
                        /* leave this one in the caller's queue for cleanup */
                } else {
                        /* callback wants to keep this packet, remove from caller's queue */
                    HTC_PACKET_REMOVE(pCallersSendQueue, pPacket);
                        /* put it in the send queue */
                    /* add HTC_FRAME_HDR space reservation again */
                    adf_nbuf_push_head(
                        GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket),
                        sizeof(HTC_FRAME_HDR));

                    HTC_PACKET_ENQUEUE(&sendQueue,pPacket);
                }

            } ITERATE_END;

            if (HTC_QUEUE_EMPTY(&sendQueue)) {
                    /* no packets made it in, caller will cleanup */
                OL_ATH_HTC_PKT_ERROR_COUNT_INCR(target,HTC_SEND_Q_EMPTY);
                result = HTC_SEND_QUEUE_DROP;
                break;
            }
        }

    } while (FALSE);

    if (result != HTC_SEND_QUEUE_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend:  \n"));
        return result;
    }

    if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) {
        tx_resources = HIFGetFreeQueueNumber(target->hif_dev,pEndpoint->UL_PipeID);
    } else {
        tx_resources = 0;
    }

    LOCK_HTC_TX(target);

    if (!HTC_QUEUE_EMPTY(&sendQueue)) {
        if (target->is_nodrop_pkt) {
            /*
            * nodrop pkts have higher priority than normal pkts, insert nodrop pkt
            * to head for proper start/termination of test.
            */
            HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&pEndpoint->TxQueue,&sendQueue);
            target->is_nodrop_pkt = FALSE;
        } else {
            /* transfer packets to tail */
            HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->TxQueue,&sendQueue);
            A_ASSERT(HTC_QUEUE_EMPTY(&sendQueue));
            INIT_HTC_PACKET_QUEUE(&sendQueue);
        }
    }

        /* increment tx processing count on entry */
    adf_os_atomic_inc(&pEndpoint->TxProcessCount);
    if (adf_os_atomic_read(&pEndpoint->TxProcessCount) > 1) {
            /* another thread or task is draining the TX queues on this endpoint
             * that thread will reset the tx processing count when the queue is drained */
        adf_os_atomic_dec(&pEndpoint->TxProcessCount);
        UNLOCK_HTC_TX(target);
        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend (busy) \n"));
        return HTC_SEND_QUEUE_OK;
    }

    /***** beyond this point only 1 thread may enter ******/

        /* now drain the endpoint TX queue for transmission as long as we have enough
         * transmit resources */
    while (TRUE) {

        if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) == 0) {
            break;
        }

        if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) {
#if DEBUG_CREDIT
            int cred = pEndpoint->TxCredits;
#endif
            /* credit based mechanism provides flow control based on target transmit resource availability, we
             * assume that the HIF layer will always have bus resources greater than target transmit resources */
            GetHTCSendPacketsCreditBased(target,pEndpoint,&sendQueue);
#if DEBUG_CREDIT
        if (ep_debug_mask & (1 << pEndpoint->Id)){
            if (cred - pEndpoint->TxCredits > 0){
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" <HTC> Decrease EP%d %d - %d = %d credits.\n",
                        pEndpoint->Id, cred, cred - pEndpoint->TxCredits, pEndpoint->TxCredits));
            }
        }
#endif
        } else {
#ifdef HIF_USB
#ifdef ENABLE_BUNDLE_TX
            /*
             * Header and payload belongs to the different fragments and
             * consume 2 resource for one HTC package but USB conbime into
             * one transfer. And one WMI message only consumes one single
             * resource.
             */
            if (HTC_ENABLE_BUNDLE(target) && tx_resources) {
                if (pEndpoint->ServiceID == WMI_CONTROL_SVC)
                    tx_resources = HTC_MAX_MSG_PER_BUNDLE_TX;
                else
                    tx_resources = (HTC_MAX_MSG_PER_BUNDLE_TX * 2);
            }
#endif
#endif
                /* get all the packets for this endpoint that we can for this pass */
            GetHTCSendPackets(target,pEndpoint,&sendQueue,tx_resources);
        }

        if (HTC_PACKET_QUEUE_DEPTH(&sendQueue) == 0) {
                /* didn't get any packets due to a lack of resources or TX queue was drained */
            break;
        }

        UNLOCK_HTC_TX(target);

            /* send what we can */
        result = HTCIssuePackets(target,pEndpoint,&sendQueue);
        if (result) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
               ("htc_issue_packets, failed status:%d put it back to head of callers SendQueue",
               result));
            LOCK_HTC_TX(target);
            HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&pEndpoint->TxQueue,
                             &sendQueue);
            break;
        }

        if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) {
            tx_resources = HIFGetFreeQueueNumber(target->hif_dev,pEndpoint->UL_PipeID);
        }

        LOCK_HTC_TX(target);

    }

        /* done with this endpoint, we can clear the count */
    adf_os_atomic_init(&pEndpoint->TxProcessCount);
    UNLOCK_HTC_TX(target);

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend:  \n"));

    return HTC_SEND_QUEUE_OK;
}

A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue)
{
    HTC_TARGET      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_ENDPOINT    *pEndpoint;
    HTC_PACKET      *pPacket;
    adf_nbuf_t      netbuf;
    HTC_FRAME_HDR       *pHtcHdr;

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCSendPktsMultiple: Queue: %pK, Pkts %d \n",
                    pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue)));

        /* get packet at head to figure out which endpoint these packets will go into */
    pPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);
    if (NULL == pPacket) {
        OL_ATH_HTC_PKT_ERROR_COUNT_INCR(target,GET_HTC_PKT_Q_FAIL);
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("-HTCSendPktsMultiple \n"));
        return A_EINVAL;
    }

    AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
    pEndpoint = &target->EndPoint[pPacket->Endpoint];

    if (!pEndpoint->ServiceID) {
       AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ServiceID is invalid\n",
                                                 __func__));
       return A_EINVAL;
    }

#ifdef HTC_EP_STAT_PROFILING
    LOCK_HTC_TX(target);
    INC_HTC_EP_STAT(pEndpoint,TxPosted,HTC_PACKET_QUEUE_DEPTH(pPktQueue));
    UNLOCK_HTC_TX(target);
#endif

    /* provide room in each packet's netbuf for the HTC frame header */
    HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
        netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
        AR_DEBUG_ASSERT(netbuf);

        adf_nbuf_push_head(netbuf, sizeof(HTC_FRAME_HDR));
        /* setup HTC frame header */
        pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0);
        AR_DEBUG_ASSERT(pHtcHdr);
        HTC_WRITE32(pHtcHdr, SM(pPacket->ActualLength, HTC_FRAME_HDR_PAYLOADLEN) |
                SM(pPacket->Endpoint, HTC_FRAME_HDR_ENDPOINTID));

            LOCK_HTC_TX(target);

            pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo;
            pEndpoint->SeqNo++;

            HTC_WRITE32(((A_UINT32 *)pHtcHdr) + 1,
                    SM(pPacket->PktInfo.AsTx.SeqNo, HTC_FRAME_HDR_CONTROLBYTES1));

            UNLOCK_HTC_TX(target);
            /*
             * Now that the HTC frame header has been added, the netbuf can be
             * mapped.  This only applies to non-data frames, since data frames
             * were already mapped as they entered into the driver.
             */
            adf_nbuf_map(
                    target->osdev,
                    GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket),
                    ADF_OS_DMA_TO_DEVICE);

	pPacket->PktInfo.AsTx.Flags |= HTC_TX_PACKET_FLAG_FIXUP_NETBUF;
    } HTC_PACKET_QUEUE_ITERATE_END;

    HTCTrySend(target,pEndpoint,pPktQueue);

        /* do completion on any packets that couldn't get in */
    if (!HTC_QUEUE_EMPTY(pPktQueue)) {

        HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
            /* remove the headroom reserved for HTC_FRAME_HDR */
            RestoreTxPacket(target, pPacket);

            if (HTC_STOPPING(target)) {
                pPacket->Status = A_ECANCELED;
            } else {
                pPacket->Status = A_NO_RESOURCE;
            }
        } HTC_PACKET_QUEUE_ITERATE_END;

        DoSendCompletion(pEndpoint,pPktQueue);
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n"));

    return A_OK;
}

/* HTC API - HTCSendPkt */
A_STATUS    HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket)
{
    HTC_PACKET_QUEUE queue;

    if (HTCHandle == NULL || pPacket == NULL) {
        return A_ERROR;
    }
    a_mem_trace(GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket));
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
                    ("+-HTCSendPkt: Enter endPointId: %d, buffer: %pK, length: %d \n",
                    pPacket->Endpoint, pPacket->pBuffer, pPacket->ActualLength));
    INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
    return HTCSendPktsMultiple(HTCHandle, &queue);
}

#ifdef ATH_11AC_TXCOMPACT

A_STATUS HTCSendDataPkt(HTC_HANDLE HTCHandle, adf_nbuf_t       netbuf, int Epid, int ActualLength)
{
    HTC_TARGET       *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_ENDPOINT     *pEndpoint;
    HTC_FRAME_HDR    *pHtcHdr;
    A_STATUS         status = A_OK;
    int              tx_resources;

    pEndpoint = &target->EndPoint[Epid];

    tx_resources = HIFGetFreeQueueNumber(target->hif_dev, pEndpoint->UL_PipeID);

    if(tx_resources <  HTC_DATA_RESOURCE_THRS){
        if (pEndpoint->ul_is_polled){
            HIFSendCompleteCheck(
                    pEndpoint->target->hif_dev, pEndpoint->UL_PipeID, 1);
            tx_resources = HIFGetFreeQueueNumber(target->hif_dev, pEndpoint->UL_PipeID);
        }
        if(tx_resources < HTC_DATA_MINDESC_PERPACKET){
            return A_ERROR;
        }
    }

    if (hif_pm_runtime_get(target->hif_dev))
        return A_ERROR;

    pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0);
    AR_DEBUG_ASSERT(pHtcHdr);

    HTC_WRITE32(pHtcHdr, SM(ActualLength, HTC_FRAME_HDR_PAYLOADLEN) |
			 SM(Epid, HTC_FRAME_HDR_ENDPOINTID));
    /*
     * If the HIF pipe for the data endpoint is polled rather than
     * interrupt-driven, this is a good point to check whether any
     * data previously sent through the HIF pipe have finished being
     * sent.
     * Since this may result in callbacks to HTCTxCompletionHandler,
     * which can take the HTC tx lock, make the HIFSendCompleteCheck
     * call before acquiring the HTC tx lock.
     * Call HIFSendCompleteCheck directly, rather than calling
     * HTCSendCompleteCheck, and call the PollTimerStart separately
     * after calling HIFSend_head, so the timer will be started to
     * check for completion of the new outstanding download (in the
     * unexpected event that other polling calls don't catch it).
     */

    LOCK_HTC_TX(target);

    HTC_WRITE32(((A_UINT32 *)pHtcHdr) + 1, SM(pEndpoint->SeqNo, HTC_FRAME_HDR_CONTROLBYTES1));

    pEndpoint->SeqNo++;

    NBUF_UPDATE_TX_PKT_COUNT(netbuf, NBUF_TX_PKT_HTC);
    DPTRACE(adf_dp_trace(netbuf, ADF_DP_TRACE_HTC_PACKET_PTR_RECORD,
                adf_nbuf_data_addr(netbuf),
                sizeof(adf_nbuf_data(netbuf)), ADF_TX));

    status = HIFSend_head(target->hif_dev,
            pEndpoint->UL_PipeID,
            pEndpoint->Id,
            ActualLength,
            netbuf);


    UNLOCK_HTC_TX(target);
    return status ;
}
#else /*ATH_11AC_TXCOMPACT*/

A_STATUS HTCSendDataPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket,
                        A_UINT8 more_data)
{
    HTC_TARGET       *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_ENDPOINT     *pEndpoint;
    HTC_FRAME_HDR    *pHtcHdr;
    HTC_PACKET_QUEUE sendQueue;
    adf_nbuf_t       netbuf;
    int              tx_resources;
    A_STATUS         status = A_OK;
    if (pPacket){
        AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
        pEndpoint = &target->EndPoint[pPacket->Endpoint];

        /* add HTC_FRAME_HDR in the initial fragment */
        netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
        pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0);
        AR_DEBUG_ASSERT(pHtcHdr);

        if (pPacket->ActualLength > (pEndpoint->TxCreditSize - HTC_HDR_LENGTH)) {
            pPacket->ActualLength = pEndpoint->TxCreditSize - HTC_HDR_LENGTH;
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                            ("Packet Length %d exceeds endpoint credit size %d, set the packet length to credit size\n",
                             pPacket->ActualLength, pEndpoint->TxCreditSize));
        }
        HTC_WRITE32(pHtcHdr, SM(pPacket->ActualLength, HTC_FRAME_HDR_PAYLOADLEN) |
                 SM(pPacket->PktInfo.AsTx.SendFlags, HTC_FRAME_HDR_FLAGS) |
                 SM(pPacket->Endpoint, HTC_FRAME_HDR_ENDPOINTID));
        /*
         * If the HIF pipe for the data endpoint is polled rather than
         * interrupt-driven, this is a good point to check whether any
         * data previously sent through the HIF pipe have finished being
         * sent.
         * Since this may result in callbacks to HTCTxCompletionHandler,
         * which can take the HTC tx lock, make the HIFSendCompleteCheck
         * call before acquiring the HTC tx lock.
         * Call HIFSendCompleteCheck directly, rather than calling
         * HTCSendCompleteCheck, and call the PollTimerStart separately
         * after calling HIFSend_head, so the timer will be started to
         * check for completion of the new outstanding download (in the
         * unexpected event that other polling calls don't catch it).
         */
        if (pEndpoint->ul_is_polled) {
            HTCSendCompletePollTimerStop(pEndpoint);
            HIFSendCompleteCheck(
                pEndpoint->target->hif_dev, pEndpoint->UL_PipeID, 0);
        }

        LOCK_HTC_TX(target);

        pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo;
        pEndpoint->SeqNo++;


        HTC_WRITE32(((A_UINT32 *)pHtcHdr) + 1, SM(pPacket->PktInfo.AsTx.SeqNo, HTC_FRAME_HDR_CONTROLBYTES1));

        /* append new packet to pEndpoint->TxQueue */
        HTC_PACKET_ENQUEUE(&pEndpoint->TxQueue, pPacket);
#ifdef ENABLE_BUNDLE_TX
        if (HTC_ENABLE_BUNDLE(target) && (more_data)) {
            UNLOCK_HTC_TX(target);
            return A_OK;
        }
#endif
    } else {
        LOCK_HTC_TX(target);
        pEndpoint = &target->EndPoint[1];
    }

    /* increment tx processing count on entry */
    adf_os_atomic_inc(&pEndpoint->TxProcessCount);
    if (adf_os_atomic_read(&pEndpoint->TxProcessCount) > 1) {
        /*
         * Another thread or task is draining the TX queues on this endpoint.
         * That thread will reset the tx processing count when the queue is
         * drained.
         */
        adf_os_atomic_dec(&pEndpoint->TxProcessCount);
        UNLOCK_HTC_TX(target);
        return A_OK;
    }

    /***** beyond this point only 1 thread may enter ******/

    INIT_HTC_PACKET_QUEUE(&sendQueue);
    if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) {
#if DEBUG_CREDIT
        int cred = pEndpoint->TxCredits;
#endif
        GetHTCSendPacketsCreditBased(target, pEndpoint, &sendQueue);
#if DEBUG_CREDIT
        if (ep_debug_mask & (1 << pEndpoint->Id)){
            if (cred - pEndpoint->TxCredits > 0){
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" <HTC> Decrease EP%d %d - %d = %d credits.\n",
                        pEndpoint->Id, cred, cred - pEndpoint->TxCredits, pEndpoint->TxCredits));
            }
        }
#endif
        UNLOCK_HTC_TX(target);
    }
#ifdef ENABLE_BUNDLE_TX
    else if (HTC_ENABLE_BUNDLE(target)) {
#ifdef HIF_USB
        if (HIFGetFreeQueueNumber(target->hif_dev, pEndpoint->UL_PipeID)) {
            /*
             * Header and payload belongs to the different fragments and
             * consume 2 resource for one HTC package but USB conbime into
             * one transfer.
             */
            GetHTCSendPackets(target, pEndpoint, &sendQueue,
                              (HTC_MAX_MSG_PER_BUNDLE_TX * 2));
        }
#else
        /* Dequeue max packets from endpoint tx queue */
        GetHTCSendPackets(target, pEndpoint, &sendQueue,
                          HTC_MAX_TX_BUNDLE_SEND_LIMIT);
#endif
        UNLOCK_HTC_TX(target);
    }
#endif
    else {
        /*
         * Now drain the endpoint TX queue for transmission as long as we have
         * enough transmit resources
         */
        tx_resources = HIFGetFreeQueueNumber(target->hif_dev,pEndpoint->UL_PipeID);
        GetHTCSendPackets(target, pEndpoint, &sendQueue, tx_resources);
        UNLOCK_HTC_TX(target);
    }
    /* send what we can */
    while (TRUE) {
#if defined(HIF_USB) || defined(HIF_SDIO)
#ifdef ENABLE_BUNDLE_TX
        if (HTC_ENABLE_BUNDLE(target) &&
           HTC_PACKET_QUEUE_DEPTH(&sendQueue) >= HTC_MIN_MSG_PER_BUNDLE) {
            HTCIssuePacketsBundle(target, pEndpoint, &sendQueue);
        }
#endif
#endif
        pPacket = HTC_PACKET_DEQUEUE(&sendQueue);
        if (pPacket == NULL){
            break;
        }
        netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);

        LOCK_HTC_TX(target);
        /* store in look up queue to match completions */
        HTC_PACKET_ENQUEUE(&pEndpoint->TxLookupQueue,pPacket);
        INC_HTC_EP_STAT(pEndpoint,TxIssued,1);
        pEndpoint->ul_outstanding_cnt++;
        UNLOCK_HTC_TX(target);

        status = HIFSend_head(target->hif_dev,
                              pEndpoint->UL_PipeID,
                              pEndpoint->Id,
                              HTC_HDR_LENGTH + pPacket->ActualLength,
                              netbuf);
#if DEBUG_BUNDLE
        adf_os_print(" Send single EP%d buffer size:0x%x, total:0x%x.\n",
            pEndpoint->Id,
            pEndpoint->TxCreditSize,
            HTC_HDR_LENGTH + pPacket->ActualLength);
#endif

#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
        target->tx_bundle_stats[0]++;
#endif

        if (adf_os_unlikely(A_FAILED(status))) {
            LOCK_HTC_TX(target);
            pEndpoint->ul_outstanding_cnt--;
            /* remove this packet from the tx completion queue */
            HTC_PACKET_REMOVE(&pEndpoint->TxLookupQueue,pPacket);

            /*
             * Don't bother reclaiming credits - HTC flow control
             * is not applicable to tx data.
             * In LL systems, there is no download flow control,
             * since there's virtually no download delay.
             * In HL systems, the txrx SW explicitly performs the
             * tx flow control.
             */
            //pEndpoint->TxCredits += pPacket->PktInfo.AsTx.CreditsUsed;

            /* put this frame back at the front of the sendQueue */
            HTC_PACKET_ENQUEUE_TO_HEAD(&sendQueue, pPacket);

            /* put the sendQueue back at the front of pEndpoint->TxQueue */
            HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&pEndpoint->TxQueue, &sendQueue);
            UNLOCK_HTC_TX(target);
            break; /* still need to reset TxProcessCount */
        }
    }
    /* done with this endpoint, we can clear the count */
    adf_os_atomic_init(&pEndpoint->TxProcessCount);

    if (pEndpoint->ul_is_polled) {
        /*
         * Start a cleanup timer to poll for download completion.
         * The download completion should be noticed promptly from
         * other polling calls, but the timer provides a safety net
         * in case other polling calls don't occur as expected.
         */
        HTCSendCompletePollTimerStart(pEndpoint);
    }

    return status;
}
#endif /*ATH_11AC_TXCOMPACT*/

/*
 * In the adapted HIF layer, adf_nbuf_t are passed between HIF and HTC, since upper layers expects
 * HTC_PACKET containers we use the completed netbuf and lookup its corresponding HTC packet buffer
 * from a lookup list.
 * This is extra overhead that can be fixed by re-aligning HIF interfaces with HTC.
 *
 */
static HTC_PACKET *HTCLookupTxPacket(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, adf_nbuf_t netbuf)
{
    HTC_PACKET *pPacket = NULL;
    HTC_PACKET *pFoundPacket = NULL;
    HTC_PACKET_QUEUE lookupQueue;

    INIT_HTC_PACKET_QUEUE(&lookupQueue);
    LOCK_HTC_TX(target);

    /* mark that HIF has indicated the send complete for another packet */
    pEndpoint->ul_outstanding_cnt--;

    /* Dequeue first packet directly because of in-order completion */
    pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxLookupQueue);
    if (adf_os_unlikely(!pPacket)) {
        UNLOCK_HTC_TX(target);
        return NULL;
    }
    if (netbuf == (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket)) {
        UNLOCK_HTC_TX(target);
        return pPacket;
    } else {
        HTC_PACKET_ENQUEUE(&lookupQueue, pPacket);
    }

    /*
     * Move TX lookup queue to temp queue because most of packets that are not index 0
     * are not top 10 packets.
     */
    HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&lookupQueue, &pEndpoint->TxLookupQueue);
    UNLOCK_HTC_TX(target);

    ITERATE_OVER_LIST_ALLOW_REMOVE(&lookupQueue.QueueHead,pPacket,HTC_PACKET,ListLink) {

        if (NULL == pPacket){
            pFoundPacket = pPacket;
            break;
        }
            /* check for removal */
        if (netbuf == (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket)) {
                /* found it */
            HTC_PACKET_REMOVE(&lookupQueue, pPacket);
            pFoundPacket = pPacket;
            break;
        }

    } ITERATE_END;

    LOCK_HTC_TX(target);
    HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&pEndpoint->TxLookupQueue, &lookupQueue);
    UNLOCK_HTC_TX(target);

    return pFoundPacket;
}


A_STATUS HTCTxCompletionHandler(void *Context,
                                adf_nbuf_t netbuf,
                                unsigned int EpID)
{
    HTC_TARGET      *target = (HTC_TARGET *)Context;
    HTC_ENDPOINT    *pEndpoint;
    HTC_PACKET      *pPacket;

    pEndpoint = &target->EndPoint[EpID];
    target->TX_comp_cnt++;

    do {
        pPacket = HTCLookupTxPacket(target, pEndpoint, netbuf);
        if (NULL == pPacket) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC TX lookup failed!\n"));
                /* may have already been flushed and freed */
            netbuf = NULL;
            break;
        }
        a_mem_trace(netbuf);

        if (pPacket->PktInfo.AsTx.Tag != HTC_TX_PACKET_TAG_AUTO_PM)
           hif_pm_runtime_put(target->hif_dev);

        if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_BUNDLED){
            HTC_PACKET      *pPacketTemp;
            HTC_PACKET_QUEUE *pQueueSave = (HTC_PACKET_QUEUE *)pPacket->pContext;
            HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQueueSave, pPacketTemp){
                pPacket->Status = A_OK;
                SendPacketCompletion(target,pPacketTemp);
            }HTC_PACKET_QUEUE_ITERATE_END;
            FreeHTCBundleTxPacket(target, pPacket);

#ifdef HIF_USB
            if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) {
                HTCTrySend(target,pEndpoint,NULL);
            }
#endif
            return A_OK;
        }
            /* will be giving this buffer back to upper layers */
        netbuf = NULL;
        pPacket->Status = A_OK;
        SendPacketCompletion(target,pPacket);

    } while (FALSE);

    if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) {
        /* note: when using TX credit flow, the re-checking of queues happens
         * when credits flow back from the target.
         * in the non-TX credit case, we recheck after the packet completes */
        HTCTrySend(target,pEndpoint,NULL);
    }

    return A_OK;
}

    /* callback when TX resources become available */
void  HTCTxResourceAvailHandler(void *context, A_UINT8 pipeID)
{
    int             i;
    HTC_TARGET      *target = (HTC_TARGET *)context;
    HTC_ENDPOINT    *pEndpoint = NULL;

    for (i = 0; i < ENDPOINT_MAX; i++) {
        pEndpoint = &target->EndPoint[i];
        if (pEndpoint->ServiceID != 0) {
            if (pEndpoint->UL_PipeID == pipeID) {
                break;
            }
        }
    }

    if (i >= ENDPOINT_MAX) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid pipe indicated for TX resource avail : %d!\n",pipeID));
        return;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HIF indicated more resources for pipe:%d \n",pipeID));

    HTCTrySend(target,pEndpoint,NULL);
}

void HTCTxResumeAllHandler(void *context)
{
	int             i;
	HTC_TARGET      *target = (HTC_TARGET *)context;
	HTC_ENDPOINT    *pEndpoint = NULL;

	for (i = 0; i < ENDPOINT_MAX; i++) {
		pEndpoint = &target->EndPoint[i];

		if (pEndpoint->ServiceID == 0)
			continue;

		if (pEndpoint->EpCallBacks.EpResumeTxQueue)
			pEndpoint->EpCallBacks.EpResumeTxQueue
					(pEndpoint->EpCallBacks.pContext);

		HTCTrySend(target, pEndpoint, NULL);
	}
}

/* flush endpoint TX queue */
void HTCFlushEndpointTX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_TX_TAG Tag)
{
    HTC_PACKET *pPacket;

    LOCK_HTC_TX(target);
    while(HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)){
        pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue);

	if (pPacket) {
		/* let the sender know the packet was not delivered */
		pPacket->Status = A_ECANCELED;
		SendPacketCompletion(target, pPacket);
	}
    }
    UNLOCK_HTC_TX(target);
}

/* HTC API to flush an endpoint's TX queue*/
void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag)
{
    HTC_TARGET      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_ENDPOINT    *pEndpoint = &target->EndPoint[Endpoint];

    if (pEndpoint->ServiceID == 0) {
        AR_DEBUG_ASSERT(FALSE);
        /* not in use.. */
        return;
    }

    HTCFlushEndpointTX(target,pEndpoint,Tag);
}

/* HTC API to indicate activity to the credit distribution function */
void HTCIndicateActivityChange(HTC_HANDLE      HTCHandle,
                               HTC_ENDPOINT_ID Endpoint,
                               A_BOOL          Active)
{
   /*  TODO */
}

A_BOOL HTCIsEndpointActive(HTC_HANDLE      HTCHandle,
                           HTC_ENDPOINT_ID Endpoint)
{
    return TRUE;
}

void HTCSetNodropPkt(HTC_HANDLE HTCHandle, A_BOOL isNodropPkt)
{
    HTC_TARGET      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    target->is_nodrop_pkt = isNodropPkt;
}

/* process credit reports and call distribution function */
void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint)
{
    int             i;
    HTC_ENDPOINT    *pEndpoint;
    int             totalCredits = 0;
    A_UINT8         rpt_credits, rpt_ep_id;

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries));

        /* lock out TX while we update credits */
    LOCK_HTC_TX(target);


    for (i = 0; i < NumEntries; i++, pRpt++) {

        rpt_ep_id = HTC_GET_FIELD(pRpt, HTC_CREDIT_REPORT, ENDPOINTID);

        if (rpt_ep_id >= ENDPOINT_MAX) {
            AR_DEBUG_ASSERT(FALSE);
            break;
        }

        rpt_credits = HTC_GET_FIELD(pRpt, HTC_CREDIT_REPORT, CREDITS);

        pEndpoint = &target->EndPoint[rpt_ep_id];
#if DEBUG_CREDIT
        if (ep_debug_mask & (1 << pEndpoint->Id)){
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" <HTC> Increase EP%d %d + %d = %d credits\n",
                    rpt_ep_id, pEndpoint->TxCredits, rpt_credits, pEndpoint->TxCredits + rpt_credits));
        }
#endif

#ifdef HTC_EP_STAT_PROFILING

        INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1);
        INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, rpt_credits);

        if (FromEndpoint == rpt_ep_id) {
                /* this credit report arrived on the same endpoint indicating it arrived in an RX
                 * packet */
            INC_HTC_EP_STAT(pEndpoint, TxCreditsFromRx, rpt_credits);
            INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromRx, 1);
        } else if (FromEndpoint == ENDPOINT_0) {
                /* this credit arrived on endpoint 0 as a NULL message */
            INC_HTC_EP_STAT(pEndpoint, TxCreditsFromEp0, rpt_credits);
            INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromEp0, 1);
        } else {
                /* arrived on another endpoint */
            INC_HTC_EP_STAT(pEndpoint, TxCreditsFromOther, rpt_credits);
            INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1);
        }

#endif
        pEndpoint->TxCredits += rpt_credits;

        if (pEndpoint->ServiceID == WMI_CONTROL_SVC) {
            LOCK_HTC_CREDIT(target);
            htc_credit_record(HTC_PROCESS_CREDIT_REPORT, pEndpoint->TxCredits,
                              HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue));
            UNLOCK_HTC_CREDIT(target);
        }

        if (pEndpoint->TxCredits && HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)) {
            UNLOCK_HTC_TX(target);
#ifdef ATH_11AC_TXCOMPACT
            HTCTrySend(target,pEndpoint,NULL);
#else
            if (pEndpoint->ServiceID == HTT_DATA_MSG_SVC){
                HTCSendDataPkt(target, NULL, 0);
            } else {
                HTCTrySend(target,pEndpoint,NULL);
            }
#endif
            LOCK_HTC_TX(target);
        }
        totalCredits += rpt_credits;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("  Report indicated %d credits to distribute \n", totalCredits));

    UNLOCK_HTC_TX(target);

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCProcessCreditRpt \n"));
}

/* function to fetch stats from htc layer*/
struct ol_ath_htc_stats *ieee80211_ioctl_get_htc_stats(HTC_HANDLE HTCHandle)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);

    return(&(target->htc_pkt_stats));
}
