/*
 * Copyright (c) 2013-2014,2016-2018 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.
 */

#define ATH_MODULE_NAME hif
#include <adf_os_types.h>
#include <adf_os_dma.h>
#include <adf_os_timer.h>
#include <adf_os_time.h>
#include <adf_os_lock.h>
#include <adf_os_io.h>
#include <adf_os_mem.h>
#include <adf_os_module.h>
#include <adf_os_util.h>
#include <adf_os_stdtypes.h>
#include <adf_os_defer.h>
#include <adf_os_atomic.h>
#include <adf_nbuf.h>
#include <vos_threads.h>
#include <athdefs.h>
#include <adf_net_types.h>
#include <a_types.h>
#include <athdefs.h>
#include <a_osapi.h>
#include <hif.h>
#include <htc_services.h>
#include "hif_sdio_internal.h"
#include "../../HTC/htc_internal.h"
#include "regtable.h"
#include "if_ath_sdio.h"

#define NBUF_ALLOC_FAIL_WAIT_TIME 100

static void HIFDevDumpRegisters(HIF_SDIO_DEVICE *pDev,
        MBOX_IRQ_PROC_REGISTERS *pIrqProcRegs,
        MBOX_IRQ_ENABLE_REGISTERS *pIrqEnableRegs,
        MBOX_COUNTER_REGISTERS *pMailBoxCounterRegisters)
{

    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("RegTable->"));

    if (pIrqProcRegs != NULL) {
        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                ("HostIntStatus: 0x%x ",pIrqProcRegs->host_int_status));
        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                ("CPUIntStatus: 0x%x ",pIrqProcRegs->cpu_int_status));
        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                ("ErrorIntStatus: 0x%x ",pIrqProcRegs->error_int_status));
        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                ("CounterIntStatus: 0x%x ",pIrqProcRegs->counter_int_status));
        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
                ("MboxFrame: 0x%x ",pIrqProcRegs->mbox_frame));

        AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\nRegTable->"));

        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                ("RxLKAValid: 0x%x ",pIrqProcRegs->rx_lookahead_valid));
        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                ("RxLKA0: 0x%x",pIrqProcRegs->rx_lookahead[0]));
        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                ("RxLKA1: 0x%x ",pIrqProcRegs->rx_lookahead[1]));

        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                ("RxLKA2: 0x%x ",pIrqProcRegs->rx_lookahead[2]));
        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                ("RxLKA3: 0x%x",pIrqProcRegs->rx_lookahead[3]));
        AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\nRegTable->"));

        if (pDev->MailBoxInfo.GMboxAddress != 0) {
            /* if the target supports GMBOX hardware, dump some additional state */
            AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                    ("GMBOX-HostIntStatus2:  0x%x ",pIrqProcRegs->host_int_status2));
            AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                    ("GMBOX-RX-Avail: 0x%x ",pIrqProcRegs->gmbox_rx_avail));
        }
    }

    if (pIrqEnableRegs != NULL) {
        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
               ("Int Status Enable:         0x%x\n",pIrqEnableRegs->int_status_enable));
        AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
               ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_status_enable));
   }

   if (pMailBoxCounterRegisters != NULL){
       int i;
       for (i = 0; i < 4; i ++){
           AR_DEBUG_PRINTF( ATH_DEBUG_ANY,
                   ("Counter[%d]:               0x%x\n", i, pMailBoxCounterRegisters->counter[i]));
       }
   }
   AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------->\n"));
}

static A_STATUS HIFDevAllocAndPrepareRxPackets(HIF_SDIO_DEVICE *pDev,
        A_UINT32 LookAheads[], int Messages, HTC_PACKET_QUEUE *pQueue)
{
    A_STATUS status = A_OK;
    HTC_PACKET *pPacket;
    HTC_FRAME_HDR *pHdr;
    int i, j;
    int numMessages;
    int fullLength;
    A_BOOL noRecycle;
#ifdef HIF_RX_THREAD
    unsigned long flags;
#endif
    HTC_TARGET *target = NULL;
    target = (HTC_TARGET *)pDev->pTarget;
    /* lock RX while we assemble the packet buffers */
    LOCK_HIF_DEV_RX(pDev);

    for (i = 0; i < Messages; i++) {

        pHdr = (HTC_FRAME_HDR *) &LookAheads[i];
        if (pHdr->EndpointID >= ENDPOINT_MAX) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                    ("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID));
            /* invalid endpoint */
            status = A_EPROTO;
            break;
        }

        if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) {
            AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                    ("Payload length %d exceeds max HTC : %d !\n", pHdr->PayloadLen, (A_UINT32)HTC_MAX_PAYLOAD_LENGTH));
            status = A_EPROTO;
            break;
        }

        numMessages = GET_RECV_BUNDLE_COUNT(pHdr->Flags);

        if (!numMessages)
        {
            /* HTC header only indicates 1 message to fetch */
            numMessages = 1;
        }
        else
        {
            /* the count doesn't include the starter frame, just a count of
               frames to follow */
            numMessages++;
            //A_ASSERT(numMessages <= target->MaxMsgPerBundle);
            AR_DEBUG_PRINTF( ATH_DEBUG_RECV,
                    ("HTC header indicates :%d messages can be fetched as a bundle \n",numMessages));
        }

        if(target->enable_b2b) {
            if(numMessages > 1)
                fullLength = target->TargetCreditSize;
            else
                fullLength = DEV_CALC_RECV_PADDED_LEN(pDev,pHdr->PayloadLen + sizeof(HTC_FRAME_HDR));
        }
        else
            fullLength = DEV_CALC_RECV_PADDED_LEN(pDev,pHdr->PayloadLen + sizeof(HTC_FRAME_HDR));

        /*
            all but the last packet have a length of payloadLen + sizeof(HTC_FRAME_HDR)
            The last packet in the bundle has an additional 16 byte lookahead information.
            This is present only if bit 0 of the flags is set
        */

        /* get packet buffers for each message, if there was a bundle detected in the header,
         * use pHdr as a template to fetch all packets in the bundle */
#ifdef HIF_RX_THREAD
        spin_lock_irqsave(&pDev->pRecvTask->rx_alloc_lock, flags);
#endif
        for (j = 0; j < numMessages; j++) {

            /* reset flag, any packets allocated using the RecvAlloc() API cannot be recycled on cleanup,
             * they must be explicitly returned */
            noRecycle = FALSE;

            /*allocate memory for the last packet*/
            if ((j == (numMessages-1)) && ((pHdr->Flags) & HTC_FLAGS_RECV_1MORE_BLOCK)) {
                fullLength += HIF_MBOX_BLOCK_SIZE;
            }

#ifdef HIF_RX_THREAD
            pPacket = HTC_PACKET_DEQUEUE(&pDev->pRecvTask->rxAllocQueue);
            if(pPacket == NULL) {
                pPacket = HIFDevAllocRxBuffer(pDev, fullLength);
            }
#else
            pPacket = HIFDevAllocRxBuffer(pDev, fullLength);
#endif

            if (pPacket == NULL) {
                /* this is not an error, we simply need to mark that we are waiting for buffers.*/
                pDev->RecvStateFlags |= HTC_RECV_WAIT_BUFFERS;
                //pDev->EpWaitingForBuffers = pEndpoint->Id;
                status = A_NO_RESOURCE;
                break;
            }
#ifdef HIF_RX_THREAD
            pPacket->BundlePktnum = 0;
#endif
            //AR_DEBUG_ASSERT(pPacket->Endpoint == pEndpoint->Id);
            /* clear flags */
            pPacket->PktInfo.AsRx.HTCRxFlags = 0;
            pPacket->PktInfo.AsRx.IndicationFlags = 0;
            pPacket->Status = A_OK;

            if (noRecycle) {
                /* flag that these packets cannot be recycled, they have to be returned to the
                 * user */
                pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_NO_RECYCLE;
            }
            /* add packet to queue (also incase we need to cleanup down below)  */
            HTC_PACKET_ENQUEUE(pQueue, pPacket);

            /*
             if (HTC_STOPPING(target)) {
             status = A_ECANCELED;
             break;
             }
             */

            /* make sure this message can fit in the endpoint buffer */
            if ((A_UINT32) fullLength > pPacket->BufferLength) {
                AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                        ("Payload Length Error : header reports payload of: %d (%d) endpoint buffer size: %d \n", pHdr->PayloadLen, fullLength, pPacket->BufferLength));
                status = A_EPROTO;
                break;
            }
            if (j > 0) {
                /* for messages fetched in a bundle the expected lookahead is unknown since we
                 * are only using the lookahead of the first packet as a template of what to
                 * expect for lengths */
                /* flag that once we get the real HTC header we need to refesh the information */
                pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_REFRESH_HDR;
                /* set it to something invalid */
                pPacket->PktInfo.AsRx.ExpectedHdr = 0xFFFFFFFF;
            } else {
                pPacket->PktInfo.AsRx.ExpectedHdr = LookAheads[i]; /* set expected look ahead */
            }
            /* set the amount of data to fetch */
            if(target->enable_b2b) {
                if(numMessages > 1)
                    pPacket->ActualLength = target->TargetCreditSize;
                else
                    pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
            }
            else
                pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;

            if ((j == (numMessages-1)) && ((pHdr->Flags) & HTC_FLAGS_RECV_1MORE_BLOCK)) {
                pPacket->PktInfo.AsRx.HTCRxFlags |=
                HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK;
            }
            pPacket->Endpoint = pHdr->EndpointID;
            pPacket->Completion = NULL;
        }
#ifdef HIF_RX_THREAD
        spin_unlock_irqrestore(&pDev->pRecvTask->rx_alloc_lock, flags);
#endif

        if (A_FAILED(status)) {
            if (A_NO_RESOURCE == status) {
                /* this is actually okay */
                status = A_OK;
            }
            break;
        }

    }

    UNLOCK_HIF_DEV_RX(pDev);

    if (A_FAILED(status)) {
        while (!HTC_QUEUE_EMPTY(pQueue)) {
            adf_nbuf_t netbuf;

            pPacket = HTC_PACKET_DEQUEUE(pQueue);
            if (pPacket == NULL)
                break;
            netbuf = (adf_nbuf_t) pPacket->pNetBufContext;
            if (netbuf)
                adf_nbuf_free(netbuf);
            }
    }
    return status;
}

#ifdef HIF_RX_THREAD
static INLINE void HIFDevPreprocessTrailer(HIF_SDIO_DEVICE *pDev, HTC_PACKET* pPacket,
                                           A_UINT32 LookAheads[], int *pNumLookAheads,
                                           A_UINT32 lookAhead_part2[])
{
    HTC_TARGET *target = NULL;
    A_UINT8 *pRecordBuf;
    HTC_RECORD_HDR *pRecord;
    HTC_LOOKAHEAD_REPORT *pLookAhead;
    HTC_LOOKAHEAD_REPORTV2 *pLookAheadV2;
    A_UINT8 *pBuffer, *pLastPktBuffer, *pCur;
    A_UINT8 lastPktFlag;
    A_UINT16 lastPktPayloadLength;
    A_UINT8 lastPktRecordID;
    int numMessages;
    A_UINT8 temp;
    A_UINT32 i;
    A_UINT16 curPayloadLen = 0;
    A_UINT32 paddedLength = 0, lastPktOffset = 0;

    target = (HTC_TARGET *)pDev->pTarget;
    pBuffer = pPacket->pBuffer;
    pLastPktBuffer = pBuffer;
    pCur = pBuffer;
    numMessages = GET_RECV_BUNDLE_COUNT(pBuffer[1]);

    if(target->enable_b2b) {
        for(i = 0; i < numMessages; i++) {
            curPayloadLen = *((A_UINT16*)(&pCur[2]));
            paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, curPayloadLen + HTC_HDR_LENGTH);
            lastPktOffset += paddedLength;
            pCur += paddedLength;
        }
    }
    else {
        curPayloadLen = *((A_UINT16*)(pBuffer + 2));
        paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, curPayloadLen + HTC_HDR_LENGTH);
        lastPktOffset = numMessages * paddedLength;
    }

    pLastPktBuffer = pBuffer + lastPktOffset;
    lastPktFlag = pLastPktBuffer[1];
    lastPktPayloadLength = ((A_UINT16)(*(A_UINT16*)(pLastPktBuffer + 2)));

    if(lastPktFlag & HTC_FLAGS_RECV_TRAILER) {
        temp = HTC_GET_FIELD(pLastPktBuffer, HTC_FRAME_HDR, CONTROLBYTES0);
        if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > lastPktPayloadLength)) {
            AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                ("%s: invalid header (payloadlength should be :%d, CB[0] is:%d) \n", __func__, lastPktPayloadLength, temp));
            return;
        }
        lastPktRecordID = *(A_UINT8*)(pLastPktBuffer + lastPktPayloadLength + 8 - temp);
        pRecord = (HTC_RECORD_HDR *)(pLastPktBuffer + lastPktPayloadLength + 8 - temp);
        pRecordBuf = (A_UINT8*)(pLastPktBuffer + lastPktPayloadLength - temp + 12);
        if(lastPktRecordID == HTC_RECORD_LOOKAHEAD) {
            if(target->enable_b2b) {
                pLookAheadV2 = (HTC_LOOKAHEAD_REPORTV2 *) pRecordBuf;
                if (pLookAheadV2->PreValid == ((~pLookAheadV2->PostValid) & 0xFF)) {
                    ((A_UINT8 *) (&LookAheads[0]))[0] = pLookAheadV2->LookAhead0;
                    ((A_UINT8 *) (&LookAheads[0]))[1] = pLookAheadV2->LookAhead1;
                    ((A_UINT8 *) (&LookAheads[0]))[2] = pLookAheadV2->LookAhead2;
                    ((A_UINT8 *) (&LookAheads[0]))[3] = pLookAheadV2->LookAhead3;

                    ((A_UINT8 *) (&lookAhead_part2[0]))[0] = pLookAheadV2->LookAhead4;
                    ((A_UINT8 *) (&lookAhead_part2[0]))[1] = pLookAheadV2->LookAhead5;
                    ((A_UINT8 *) (&lookAhead_part2[0]))[2] = pLookAheadV2->LookAhead6;
                    ((A_UINT8 *) (&lookAhead_part2[0]))[3] = pLookAheadV2->LookAhead7;
                    if (pNumLookAheads != NULL) {
                        *pNumLookAheads = 1;
                    }
                    return;
                }
            }
            else {
                pLookAhead = (HTC_LOOKAHEAD_REPORT *) pRecordBuf;
                if (pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) {
                    ((A_UINT8 *) (&LookAheads[0]))[0] = pLookAhead->LookAhead0;
                    ((A_UINT8 *) (&LookAheads[0]))[1] = pLookAhead->LookAhead1;
                    ((A_UINT8 *) (&LookAheads[0]))[2] = pLookAhead->LookAhead2;
                    ((A_UINT8 *) (&LookAheads[0]))[3] = pLookAhead->LookAhead3;
                    if (pNumLookAheads != NULL) {
                        *pNumLookAheads = 1;
                    }
                }
                return;
            }
        }
        else if (lastPktRecordID == HTC_RECORD_LOOKAHEAD_BUNDLE) {
            if(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT)) {
                HTC_BUNDLED_LOOKAHEAD_REPORT *pBundledLookAheadRpt;
                int i;

                pBundledLookAheadRpt =
                        (HTC_BUNDLED_LOOKAHEAD_REPORT *) pRecordBuf;

                if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
                    DebugDumpBytes(pRecordBuf,
                            pRecord->Length,
                            "Bundle LookAhead");
                }

                if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT)))
                        > HTC_MAX_MSG_PER_BUNDLE_RX) {
                    /* this should never happen, the target restricts the number
                     * of messages per bundle configured by the host */
                    A_ASSERT(FALSE);
                    return ;
                }
                for (i = 0; i< (int) (pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) {
                    ((A_UINT8 *) (&LookAheads[i]))[0] =
                            pBundledLookAheadRpt->LookAhead0;
                    ((A_UINT8 *) (&LookAheads[i]))[1] =
                            pBundledLookAheadRpt->LookAhead1;
                    ((A_UINT8 *) (&LookAheads[i]))[2] =
                            pBundledLookAheadRpt->LookAhead2;
                    ((A_UINT8 *) (&LookAheads[i]))[3] =
                            pBundledLookAheadRpt->LookAhead3;
                    pBundledLookAheadRpt++;
                }

                if (pNumLookAheads != NULL) {
                    *pNumLookAheads = i;
                }

            }
        }
    }
}
#endif

static INLINE A_STATUS HIFDevRecvPacket(HIF_SDIO_DEVICE *pDev,
    HTC_PACKET *pPacket,
    A_UINT32 RecvLength,
    A_UINT8 mboxIndex)
{
    A_UINT32 paddedLength;
    A_STATUS status;
    A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;

    /* adjust the length to be a multiple of block size if appropriate */
    paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength);

    if (paddedLength > pPacket->BufferLength) {
        AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n", paddedLength,RecvLength,pPacket->BufferLength));
        if (pPacket->Completion != NULL) {
            COMPLETE_HTC_PACKET(pPacket, A_EINVAL);
            return A_OK;
        }
        return A_EINVAL;
    }

    /* mailbox index is saved in Endpoint member */
    AR_DEBUG_PRINTF( ATH_DEBUG_RECV,
        ("HIFDevRecvPacket (0x%lX : hdr:0x%X) Len:%d, Padded Length: %d Mbox:0x%X\n",
         (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
         RecvLength,
         paddedLength,
         pDev->MailBoxInfo.MboxAddresses[mboxIndex]));

#ifdef HIF_SYNC_READ
    status = HIFSyncRead(pDev->HIFDevice,
                pDev->MailBoxInfo.MboxAddresses[mboxIndex],
                pPacket->pBuffer,
                paddedLength,
                (sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX),
                sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
#else
    status = HIFReadWrite(pDev->HIFDevice,
                pDev->MailBoxInfo.MboxAddresses[mboxIndex],
                pPacket->pBuffer,
                paddedLength,
                (sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX),
                sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
#endif

    AR_DEBUG_PRINTF( ATH_DEBUG_RECV, ("EP%d, Seq:%d\n",
           ((HTC_FRAME_HDR*)pPacket->pBuffer)->EndpointID,
           ((HTC_FRAME_HDR*)pPacket->pBuffer)->ControlBytes1));
    if (status != A_OK) {
        AR_DEBUG_PRINTF( ATH_DEBUG_RECV,
                ("HIFDevRecvPacket (0x%lX : hdr:0x%X) Failed\n", (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr));
    }
    if (sync) {
        pPacket->Status = status;
        if (status == A_OK) {
            HTC_FRAME_HDR *pHdr = (HTC_FRAME_HDR *) pPacket->pBuffer;
            AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
                    ("HIFDevRecvPacket "
                    "EP:%d,PayloadLen:%d,Flag:%d,CB:0x%02X,0x%02X\n",
                    pHdr->EndpointID,
                    pHdr->PayloadLen,
                    pHdr->Flags,
                    pHdr->ControlBytes0,
                    pHdr->ControlBytes1));
        }
    }

    return status;
}

static INLINE A_STATUS HIFDevProcessTrailer(HIF_SDIO_DEVICE *pDev,
        A_UINT8 *pBuffer, int Length, A_UINT32 *pNextLookAheads,
        int *pNumLookAheads, HTC_ENDPOINT_ID FromEndpoint,
        A_UINT32 lookAhead_part2[])
{
    HTC_TARGET *target = NULL;
    HTC_RECORD_HDR *pRecord;
    A_UINT8 *pRecordBuf;
    HTC_LOOKAHEAD_REPORT *pLookAhead;
    HTC_LOOKAHEAD_REPORTV2 *pLookAheadV2;
    A_UINT8 *pOrigBuffer;
    int origLength;
    A_STATUS status;

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
            ("+HTCProcessTrailer (length:%d) \n", Length));

    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
        AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer");
    }

    target = (HTC_TARGET *)pDev->pTarget;
    pOrigBuffer = pBuffer;
    origLength = Length;
    status = A_OK;

    while (Length > 0) {

        if (Length < sizeof(HTC_RECORD_HDR)) {
            status = A_EPROTO;
            break;
        }
        /* these are byte aligned structs */
        pRecord = (HTC_RECORD_HDR *) pBuffer;
        Length -= sizeof(HTC_RECORD_HDR);
        pBuffer += sizeof(HTC_RECORD_HDR);

        if (pRecord->Length > Length) {
            /* no room left in buffer for record */
            AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                    (" invalid record length: %d (id:%d) buffer has: %d bytes left \n", pRecord->Length, pRecord->RecordID, Length));
            status = A_EPROTO;
            break;
        }
        /* start of record follows the header */
        pRecordBuf = pBuffer;

        switch (pRecord->RecordID) {
        case HTC_RECORD_CREDITS:
            /* Process in HTC, ignore here*/
            break;
        case HTC_RECORD_LOOKAHEAD:
            AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_LOOKAHEAD_REPORT));
            if(target->enable_b2b) {
                pLookAheadV2 = (HTC_LOOKAHEAD_REPORTV2 *) pRecordBuf;
                if ((pLookAheadV2->PreValid == ((~pLookAheadV2->PostValid) & 0xFF))
                        && (pNextLookAheads != NULL)) {

                    AR_DEBUG_PRINTF( ATH_DEBUG_RECV,
                        (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) %d %d\n",
                               pLookAheadV2->PreValid, pLookAheadV2->PostValid,
                               FromEndpoint,
                               pLookAheadV2->LookAhead0
                               ));
                    /* look ahead bytes are valid, copy them over */
                    ((A_UINT8 *) (&pNextLookAheads[0]))[0] = pLookAheadV2->LookAhead0;
                    ((A_UINT8 *) (&pNextLookAheads[0]))[1] = pLookAheadV2->LookAhead1;
                    ((A_UINT8 *) (&pNextLookAheads[0]))[2] = pLookAheadV2->LookAhead2;
                    ((A_UINT8 *) (&pNextLookAheads[0]))[3] = pLookAheadV2->LookAhead3;

                    ((A_UINT8 *) (&lookAhead_part2[0]))[0] = pLookAheadV2->LookAhead4;
                    ((A_UINT8 *) (&lookAhead_part2[0]))[1] = pLookAheadV2->LookAhead5;
                    ((A_UINT8 *) (&lookAhead_part2[0]))[2] = pLookAheadV2->LookAhead6;
                    ((A_UINT8 *) (&lookAhead_part2[0]))[3] = pLookAheadV2->LookAhead7;
                    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
                        DebugDumpBytes((A_UINT8 *) pNextLookAheads,
                                4,
                                "Next Look Ahead");
                    }
                    /* just one normal lookahead */
                    if (pNumLookAheads != NULL) {
                        *pNumLookAheads = 1;
                    }
                }
            }
            else {
                pLookAhead = (HTC_LOOKAHEAD_REPORT *) pRecordBuf;
                if ((pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF))
                        && (pNextLookAheads != NULL)) {

                    AR_DEBUG_PRINTF( ATH_DEBUG_RECV,
                        (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) %d %d\n",
                               pLookAhead->PreValid, pLookAhead->PostValid,
                               FromEndpoint,
                               pLookAhead->LookAhead0
                               ));
                    /* look ahead bytes are valid, copy them over */
                    ((A_UINT8 *) (&pNextLookAheads[0]))[0] = pLookAhead->LookAhead0;
                    ((A_UINT8 *) (&pNextLookAheads[0]))[1] = pLookAhead->LookAhead1;
                    ((A_UINT8 *) (&pNextLookAheads[0]))[2] = pLookAhead->LookAhead2;
                    ((A_UINT8 *) (&pNextLookAheads[0]))[3] = pLookAhead->LookAhead3;
                    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
                        DebugDumpBytes((A_UINT8 *) pNextLookAheads,
                                4,
                                "Next Look Ahead");
                    }
                    /* just one normal lookahead */
                    if (pNumLookAheads != NULL) {
                        *pNumLookAheads = 1;
                    }
                }
            }
            break;
        case HTC_RECORD_LOOKAHEAD_BUNDLE:
            AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT));
            if (pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT)
                    && (pNextLookAheads != NULL)) {
                HTC_BUNDLED_LOOKAHEAD_REPORT *pBundledLookAheadRpt;
                int i;

                pBundledLookAheadRpt =
                        (HTC_BUNDLED_LOOKAHEAD_REPORT *) pRecordBuf;

                if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
                    DebugDumpBytes(pRecordBuf,
                            pRecord->Length,
                            "Bundle LookAhead");
                }

                if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT)))
                        > HTC_MAX_MSG_PER_BUNDLE_RX) {
                    /* this should never happen, the target restricts the number
                     * of messages per bundle configured by the host */
                    A_ASSERT(FALSE);
                    status = A_EPROTO;
                    break;
                }
                for (i = 0; i< (int) (pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) {
                    ((A_UINT8 *) (&pNextLookAheads[i]))[0] =
                            pBundledLookAheadRpt->LookAhead0;
                    ((A_UINT8 *) (&pNextLookAheads[i]))[1] =
                            pBundledLookAheadRpt->LookAhead1;
                    ((A_UINT8 *) (&pNextLookAheads[i]))[2] =
                            pBundledLookAheadRpt->LookAhead2;
                    ((A_UINT8 *) (&pNextLookAheads[i]))[3] =
                            pBundledLookAheadRpt->LookAhead3;
                    pBundledLookAheadRpt++;
                }

                if (pNumLookAheads != NULL) {
                    *pNumLookAheads = i;
                }
            }
            break;
        default:
            AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                (" HIF unhandled record: id:%d length:%d \n", pRecord->RecordID, pRecord->Length));
            break;
        }

        if (A_FAILED(status)) {
            break;
        }

        /* advance buffer past this record for next time around */
        pBuffer += pRecord->Length;
        Length -= pRecord->Length;
    }

    if (A_FAILED(status)) {
        DebugDumpBytes(pOrigBuffer, origLength, "BAD Recv Trailer");
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n"));
    return status;
}

/* process a received message (i.e. strip off header, process any trailer data)
 * note : locks must be released when this function is called */
static A_STATUS HIFDevProcessRecvHeader(HIF_SDIO_DEVICE *pDev,
        HTC_PACKET *pPacket, A_UINT32 *pNextLookAheads, int *pNumLookAheads,
        bool processTrailer, A_UINT32 lookAhead_part2[])
{
    A_UINT8 temp;
    A_UINT8 *pBuf;
    A_STATUS status = A_OK;
    A_UINT16 payloadLen;
    A_UINT32 lookAhead, ActualLength;

    pBuf = pPacket->pBuffer;
    ActualLength = pPacket->ActualLength;

    if (pNumLookAheads != NULL) {
        *pNumLookAheads = 0;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessRecvHeader \n"));

    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
        AR_DEBUG_PRINTBUF(pBuf,pPacket->ActualLength,"HTC Recv PKT");
    }

    do {
        /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to
         * retrieve 16 bit fields */
        payloadLen = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, PAYLOADLEN);

        ((A_UINT8 *) &lookAhead)[0] = pBuf[0];
        ((A_UINT8 *) &lookAhead)[1] = pBuf[1];
        ((A_UINT8 *) &lookAhead)[2] = pBuf[2];
        ((A_UINT8 *) &lookAhead)[3] = pBuf[3];

        if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_REFRESH_HDR) {
            /* refresh expected hdr, since this was unknown at the time we grabbed the packets
             * as part of a bundle */
            pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead;
            /* refresh actual length since we now have the real header */
            pPacket->ActualLength = payloadLen + HTC_HDR_LENGTH;

            /* validate the actual header that was refreshed  */
            if (pPacket->ActualLength > pPacket->BufferLength) {
                AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                        ("Refreshed HDR payload length (%d) in bundled RECV is invalid (hdr: 0x%X) \n", payloadLen, lookAhead));
                /* limit this to max buffer just to print out some of the buffer */
                pPacket->ActualLength =
                min(pPacket->ActualLength, pPacket->BufferLength);
                status = A_EPROTO;
                break;
            }

            if (pPacket->Endpoint
                    != HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, ENDPOINTID)) {
                AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                        ("Refreshed HDR endpoint (%d) does not match expected endpoint (%d) \n", HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, ENDPOINTID), pPacket->Endpoint));
                status = A_EPROTO;
                break;
            }
        }

        if (lookAhead != pPacket->PktInfo.AsRx.ExpectedHdr) {
            /* somehow the lookahead that gave us the full read length did not
             * reflect the actual header in the pending message */
            AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                ("HIFDevProcessRecvHeader, lookahead mismatch! (pPkt:%p flags:0x%X), 0x%08X != 0x%08X len %d\n",
                           pPacket, pPacket->PktInfo.AsRx.HTCRxFlags,
                           lookAhead, pPacket->PktInfo.AsRx.ExpectedHdr, payloadLen));
#ifdef ATH_DEBUG_MODULE
            DebugDumpBytes((A_UINT8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead");
            DebugDumpBytes(pBuf,sizeof(HTC_FRAME_HDR),"Current Frame Header");
#ifdef HTC_CAPTURE_LAST_FRAME
            DebugDumpBytes((A_UINT8 *)&target->LastFrameHdr,sizeof(HTC_FRAME_HDR),"Last Frame Header");
            if (target->LastTrailerLength != 0) {
                DebugDumpBytes(target->LastTrailer,
                        target->LastTrailerLength,
                        "Last trailer");
            }
#endif
#endif
            status = A_EPROTO;
            break;
        }

#ifdef HIF_RX_THREAD
        if(processTrailer == TRUE) {
#endif
            /* get flags */
            temp = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, FLAGS);

            if (temp & HTC_FLAGS_RECV_TRAILER) {
                /* this packet has a trailer */

                /* extract the trailer length in control byte 0 */
                temp = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, CONTROLBYTES0);

                if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) {
                    AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                        ("HIFDevProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n", payloadLen, temp));
                    status = A_EPROTO;
                    break;
                }

                if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
                    /* this packet was fetched as part of an HTC bundle, the embedded lookahead is
                     * not valid since the next packet may have already been fetched as part of the
                     * bundle */
                    pNextLookAheads = NULL;
                    pNumLookAheads = NULL;
                }

                /* process trailer data that follows HDR + application payload */
                status = HIFDevProcessTrailer(pDev,
                        (pBuf + HTC_HDR_LENGTH + payloadLen - temp),
                        temp,
                        pNextLookAheads,
                        pNumLookAheads,
                        pPacket->Endpoint,
                        lookAhead_part2);

                if (A_FAILED(status)) {
                    break;
                }
            }
#ifdef HIF_RX_THREAD
        }
#endif
    }while (FALSE);

    if (A_FAILED(status)) {
        /* dump the whole packet */
        DebugDumpBytes(pBuf,
            pPacket->ActualLength,
            "BAD HTC Recv PKT");
    } else {
        if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
            if (pPacket->ActualLength > 0) {
                AR_DEBUG_PRINTBUF(pPacket->pBuffer,pPacket->ActualLength,"HTC - Application Msg");
            }
        }
    }
    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HIFDevProcessRecvHeader \n"));
    return status;
}

#ifdef HIF_RX_THREAD
static A_STATUS processHdrAndRxComp(HIF_SDIO_DEVICE *device, HTC_PACKET *pPacket, bool processTrailer)
{
    A_UINT8 pipeid;
    adf_nbuf_t netbuf;
    int NumLookAheads;
    A_UINT32 lookAheads[HTC_MAX_MSG_PER_BUNDLE_RX];
    A_UINT32 lookAhead_part2[HTC_MAX_MSG_PER_BUNDLE_RX];
    A_STATUS status = A_OK;

    NumLookAheads = 0;
    status = HIFDevProcessRecvHeader(device, pPacket, lookAheads, &NumLookAheads,
                                     processTrailer, lookAhead_part2);
    if (A_FAILED(status)) {
        return status;
    }

    netbuf = (adf_nbuf_t) pPacket->pNetBufContext;
    /* set data length */
    adf_nbuf_put_tail(netbuf, pPacket->ActualLength);

    if (device->hif_callbacks.rxCompletionHandler) {
        pipeid = HIFDevMapMailBoxToPipe(device, 0, TRUE);
        device->hif_callbacks.rxCompletionHandler(device->hif_callbacks.Context,
            netbuf,
            pipeid);
    }
    return status;
}

int rx_completion_task(void *param)
{
    HIF_SDIO_DEVICE *device;
    HTC_PACKET *pPacket = NULL;
    unsigned long flags;
    HTC_PACKET *pPacketRxBundle;
    A_UINT32 paddedLength;
    unsigned char    *pBundleBuffer = NULL;
    unsigned char *pBuffer;
    HTC_TARGET *target = NULL;
    A_UINT8 syncQDepth = 0;
    A_UINT8 nextIsSingle = 0;
    A_UINT16 curPayloadLen = 0;
    A_STATUS status = A_OK;

    device = (HIF_SDIO_DEVICE *)param;
    target = (HTC_TARGET *)device->pTarget;
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: rx completion task\n"));

    set_current_state(TASK_INTERRUPTIBLE);
    vos_set_cpus_allowed_ptr(current, 1);

    while (!device->pRecvTask->rx_completion_shutdown) {
        if (down_interruptible(&device->pRecvTask->sem_rx_completion) != 0) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                        ("%s: rx completion task interrupted\n",
                         __func__));
                break;
        }

        if (device->pRecvTask->rx_completion_shutdown) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                        ("%s: rx completion task stopping\n",
                         __func__));
                break;
        }

        //process single packet
        spin_lock_irqsave(&device->pRecvTask->rx_bundle_lock, flags);
        if(HTC_QUEUE_EMPTY(&device->pRecvTask->rxBundleQueue)) {
            spin_lock_irqsave(&device->pRecvTask->rx_sync_completion_lock, flags);
            while(!HTC_QUEUE_EMPTY(&device->pRecvTask->rxSyncCompletionQueue)) {
                pPacket = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxSyncCompletionQueue);
                if(pPacket == NULL) {
                    break;
                }
                status = processHdrAndRxComp(device, pPacket, FALSE);

                if (A_FAILED(status)) {
                    break;
                }
            }
            spin_unlock_irqrestore(&device->pRecvTask->rx_sync_completion_lock, flags);
        }
        else {
            //1. Dequeue from bundle buffer queue, scatter data to sync completion queue
            while(!HTC_QUEUE_EMPTY(&device->pRecvTask->rxBundleQueue)) {
                pPacketRxBundle = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxBundleQueue);
                if(pPacketRxBundle == NULL) {
                    break;
                }
                if(pPacketRxBundle->BundlePktnum < 1) {
                    AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Packets in bundle buffer is < 1"));
                    break;
                }
                spin_lock_irqsave(&device->pRecvTask->rx_sync_completion_lock, flags);
                if(HTC_PACKET_QUEUE_DEPTH(&device->pRecvTask->rxSyncCompletionQueue) < pPacketRxBundle->BundlePktnum) {
                    // corner case: the sync queue depth is not enough for processing this bundle pkt, push it back
                    HTC_PACKET_ENQUEUE_TO_HEAD(&device->pRecvTask->rxBundleQueue, pPacketRxBundle);
                    spin_unlock_irqrestore(&device->pRecvTask->rx_sync_completion_lock, flags);
                    break;
                }
                spin_unlock_irqrestore(&device->pRecvTask->rx_sync_completion_lock, flags);
                pBundleBuffer = pPacketRxBundle->pBuffer;
                pBuffer = pBundleBuffer;
                if(pPacketRxBundle == NULL)
                    break;

                spin_lock_irqsave(&device->pRecvTask->rx_sync_completion_lock, flags);
                //if the next pkt is single, dequeue it and process it, until the bundle pkts
                while(TRUE) {
                    nextIsSingle = 0;
                    pPacket = HTC_GET_PKT_AT_HEAD(&device->pRecvTask->rxSyncCompletionQueue);
                    if(pPacket == NULL)
                        break;
                    if(pPacket->BundlePktnum == 1) {
                        nextIsSingle = 1;
                    }
                    if(nextIsSingle == 1) {
                        pPacket = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxSyncCompletionQueue);
                        if(pPacket == NULL)
                            break;

                        status = processHdrAndRxComp(device, pPacket, FALSE);

                        if (A_FAILED(status)) {
                            break;
                        }
                    }
                    else
                        break;
                }

                //2. Dequeue from sync completion queue for processing header, the trialer info at this point is useless.
                syncQDepth = 0;
                while(!HTC_QUEUE_EMPTY(&device->pRecvTask->rxSyncCompletionQueue)) {
                    pPacket = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxSyncCompletionQueue);
                    if(pPacket == NULL)
                        break;
                    syncQDepth++;
                    if(target->enable_b2b) {
                        curPayloadLen = *(A_UINT16*)(&pBuffer[2]);
                        pPacket->ActualLength = curPayloadLen + HTC_HDR_LENGTH;
                        paddedLength = DEV_CALC_RECV_PADDED_LEN(device, pPacket->ActualLength);
                    }
                    else {
                        paddedLength = DEV_CALC_RECV_PADDED_LEN(device, pPacket->ActualLength);
                        if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK){
                                paddedLength += HIF_MBOX_BLOCK_SIZE;
                        }
                    }
                    A_MEMCPY(pPacket->pBuffer, pBuffer, paddedLength);
                    pBuffer += paddedLength;
                    status = processHdrAndRxComp(device, pPacket, FALSE);
                    if (A_FAILED(status)) {
                        break;
                    }

                    if(syncQDepth > (pPacketRxBundle->BundlePktnum - 1))
                        break;
                }
                //if the next pkt is single, dequeue it and process it, until the bundle pkts
                while(TRUE) {
                    nextIsSingle = 0;
                    pPacket = HTC_GET_PKT_AT_HEAD(&device->pRecvTask->rxSyncCompletionQueue);
                    if(pPacket == NULL)
                        break;
                    if(pPacket->BundlePktnum == 1) {
                        nextIsSingle = 1;
                    }
                    if(nextIsSingle == 1) {
                        pPacket = HTC_PACKET_DEQUEUE(&device->pRecvTask->rxSyncCompletionQueue);
                        if(pPacket == NULL)
                            break;
                        status = processHdrAndRxComp(device, pPacket, FALSE);
                        if (A_FAILED(status)) {
                            break;
                        }
                    }
                    else
                        break;
                }
                spin_unlock_irqrestore(&device->pRecvTask->rx_sync_completion_lock, flags);
                FreeHTCBundleRxPacket(target, pPacketRxBundle);
            }
        }
        spin_unlock_irqrestore(&device->pRecvTask->rx_bundle_lock, flags);
        //alloc skb for next bundle
        spin_lock_irqsave(&device->pRecvTask->rx_alloc_lock, flags);
        while(HTC_PACKET_QUEUE_DEPTH(&device->pRecvTask->rxAllocQueue) < 64) {
            pPacket = HIFDevAllocRxBuffer(device, 2048);
            if(pPacket == NULL) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Short of mem, alloc failed"));
                break;
            }
            HTC_PACKET_ENQUEUE(&device->pRecvTask->rxAllocQueue, pPacket);
        }
        spin_unlock_irqrestore(&device->pRecvTask->rx_alloc_lock, flags);
    }
    complete_and_exit(&device->pRecvTask->rx_completion_exit, 0);
    return 0;
}
#endif

static A_STATUS HIFDevIssueRecvPacketBundle(HIF_SDIO_DEVICE *pDev,
        HTC_PACKET_QUEUE *pRecvPktQueue,
        HTC_PACKET_QUEUE *pSyncCompletionQueue,
        A_UINT8 MailBoxIndex,
        int *pNumPacketsFetched,
        A_BOOL  PartialBundle
#ifdef HIF_RX_THREAD
        , int *pNumLookAheads
        , A_UINT32 LookAheads[]
#endif
        , A_UINT32 lookAhead_part2[]
        )
{ A_STATUS status = A_OK;
    int i, totalLength = 0;
    unsigned char    *pBundleBuffer = NULL;
    HTC_PACKET *pPacket, *pPacketRxBundle;
    HTC_TARGET *target = NULL;
    A_UINT32 paddedLength;
#ifdef HIF_RX_THREAD
    unsigned long flags;
#else
    unsigned char *pBuffer = NULL;
    A_UINT16 curPayloadLen = 0;
#endif
    int bundleSpaceRemaining = 0;
    target = (HTC_TARGET *)pDev->pTarget;

    if (!pSyncCompletionQueue) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                  ("%s: pSyncCompletionQueue is NULL\n", __func__));
        return A_ERROR;
    }

    if((HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) - HTC_MAX_MSG_PER_BUNDLE_RX) > 0){
        PartialBundle = TRUE;
        AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("%s, partial bundle detected num: %d, %d \n",
                __FUNCTION__, HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue),  HTC_MAX_MSG_PER_BUNDLE_RX));
    }

    bundleSpaceRemaining = HTC_MAX_MSG_PER_BUNDLE_RX * target->TargetCreditSize;
    pPacketRxBundle = AllocateHTCBundleRxPacket(target);
    if (!pPacketRxBundle) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: pPacketRxBundle is NULL \n",
            __FUNCTION__));
        vos_sleep(NBUF_ALLOC_FAIL_WAIT_TIME);  /* 100 msec sleep */
        return A_NO_MEMORY;
    }
    pBundleBuffer = pPacketRxBundle->pBuffer;

    for(i = 0; !HTC_QUEUE_EMPTY(pRecvPktQueue) && i < HTC_MAX_MSG_PER_BUNDLE_RX; i++){
        pPacket = HTC_PACKET_DEQUEUE(pRecvPktQueue);
        if (pPacket == NULL)
            break;
        if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK)
            paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, pPacket->ActualLength)
                                                    + HIF_MBOX_BLOCK_SIZE;
        else
            paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, pPacket->ActualLength);

        if((bundleSpaceRemaining - paddedLength) < 0){
            /* exceeds what we can transfer, put the packet back */
            HTC_PACKET_ENQUEUE_TO_HEAD(pRecvPktQueue, pPacket);
            break;
        }
        bundleSpaceRemaining -= paddedLength;

        if(PartialBundle || HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) > 0){
            pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
        }
        pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_PART_OF_BUNDLE;

        HTC_PACKET_ENQUEUE(pSyncCompletionQueue, pPacket);

        totalLength += paddedLength;
    }
    if(target->enable_b2b)
        totalLength = (A_UINT16)((lookAhead_part2[0] & 0xffff0000) >> 16);
#if DEBUG_BUNDLE
    adf_os_print("Recv bundle count %d, length %d.\n",
       HTC_PACKET_QUEUE_DEPTH(pSyncCompletionQueue), totalLength);
#endif

#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
    if (HTC_PACKET_QUEUE_DEPTH(pSyncCompletionQueue) <= HTC_MAX_MSG_PER_BUNDLE_RX)
        target->rx_bundle_stats[HTC_PACKET_QUEUE_DEPTH(pSyncCompletionQueue) - 1]++;
#endif


#ifdef HIF_SYNC_READ
    status = HIFSyncRead(pDev->HIFDevice,
                pDev->MailBoxInfo.MboxAddresses[(int)MailBoxIndex],
                pBundleBuffer,
                totalLength,
                HIF_RD_SYNC_BLOCK_FIX,
                NULL);
#else
    status = HIFReadWrite(pDev->HIFDevice,
                pDev->MailBoxInfo.MboxAddresses[(int)MailBoxIndex],
                pBundleBuffer,
                totalLength,
                HIF_RD_SYNC_BLOCK_FIX,
                NULL);
#endif

    if(status != A_OK){
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s, HIFSend Failed status:%d \n",__FUNCTION__, status));
    }else{
#ifdef HIF_RX_THREAD
        HIFDevPreprocessTrailer(pDev, pPacketRxBundle, LookAheads,
                                pNumLookAheads, lookAhead_part2);
        *pNumPacketsFetched = i;
        pPacketRxBundle->BundlePktnum = i;
        spin_lock_irqsave(&pDev->pRecvTask->rx_bundle_lock, flags);
        HTC_PACKET_ENQUEUE(&pDev->pRecvTask->rxBundleQueue, pPacketRxBundle);
        spin_unlock_irqrestore(&pDev->pRecvTask->rx_bundle_lock, flags);

        spin_lock_irqsave(&pDev->pRecvTask->rx_sync_completion_lock, flags);
        HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pDev->pRecvTask->rxSyncCompletionQueue,
                                          pSyncCompletionQueue);
        spin_unlock_irqrestore(&pDev->pRecvTask->rx_sync_completion_lock, flags);
#else
        *pNumPacketsFetched = i;
        pBuffer = pBundleBuffer;
        HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pSyncCompletionQueue, pPacket){
            if(target->enable_b2b) {
                curPayloadLen = *(A_UINT16*)(&pBuffer[2]);
                pPacket->ActualLength = curPayloadLen + HTC_HDR_LENGTH;
                paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, pPacket->ActualLength);
            }
            else {
                paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, pPacket->ActualLength);
                if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK) {
                        paddedLength += HIF_MBOX_BLOCK_SIZE;
                }
            }
            A_MEMCPY(pPacket->pBuffer, pBuffer, paddedLength);
            pBuffer += paddedLength;
        }HTC_PACKET_QUEUE_ITERATE_END;
#endif
    }
#ifndef HIF_RX_THREAD
    /* free bundle space under Sync mode */
    FreeHTCBundleRxPacket(target, pPacketRxBundle);
#endif
    return status;
}

A_STATUS HIFDevRecvMessagePendingHandler(HIF_SDIO_DEVICE *pDev,
        A_UINT8 MailBoxIndex,
        A_UINT32 MsgLookAheads[],
        int NumLookAheads,
        A_BOOL *pAsyncProc,
        int *pNumPktsFetched,
        A_UINT32 LookAhead_Part2[])
{
    A_STATUS status = A_OK;
    HTC_PACKET *pPacket;
    A_BOOL asyncProc = FALSE;
    A_UINT32 lookAheads[HTC_MAX_MSG_PER_BUNDLE_RX];
    A_UINT32 lookAhead_part2[HTC_MAX_MSG_PER_BUNDLE_RX];
    int pktsFetched;
    HTC_PACKET_QUEUE recvPktQueue, syncCompletedPktsQueue;
    A_BOOL partialBundle;
    HTC_ENDPOINT_ID id;
    int totalFetched = 0;
#ifdef HIF_RX_THREAD
    unsigned long flags;
#endif

    HTC_TARGET *target = NULL;

    AR_DEBUG_PRINTF( ATH_DEBUG_RECV,
            ("+HTCRecvMessagePendingHandler NumLookAheads: %d \n", NumLookAheads));

    if (pNumPktsFetched != NULL) {
        *pNumPktsFetched = 0;
    }

    if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev)) {
        /* We use async mode to get the packets if the device layer supports it.
         * The device layer interfaces with HIF in which HIF may have restrictions on
         * how interrupts are processed */
        asyncProc = TRUE;
    }

    if (pAsyncProc != NULL) {
        /* indicate to caller how we decided to process this */
        *pAsyncProc = asyncProc;
    }
    if (NumLookAheads > HTC_MAX_MSG_PER_BUNDLE_RX) {
        A_ASSERT(FALSE);
        return A_EPROTO;
    }
    A_MEMCPY(lookAheads, MsgLookAheads, (sizeof(A_UINT32)) * NumLookAheads);
    A_MEMCPY(lookAhead_part2, LookAhead_Part2, (sizeof(A_UINT32)) * NumLookAheads);

    target = (HTC_TARGET *)pDev->pTarget;
    id = ((HTC_FRAME_HDR *) &lookAheads[0])->EndpointID;

#ifdef HTC_EP_STAT_PROFILING
    LOCK_HTC_RX(target);
    INC_HTC_EP_STAT(&target->EndPoint[id],HIFDSRCount,1);
    UNLOCK_HTC_RX(target);
#endif


    while (TRUE) {

        /* reset packets queues */
        INIT_HTC_PACKET_QUEUE(&recvPktQueue);
        INIT_HTC_PACKET_QUEUE(&syncCompletedPktsQueue);
        if (NumLookAheads > HTC_MAX_MSG_PER_BUNDLE_RX) {
            status = A_EPROTO;
            A_ASSERT(FALSE);
            break;
        }
        /* first lookahead sets the expected endpoint IDs for all packets in a bundle */
        id = ((HTC_FRAME_HDR *) &lookAheads[0])->EndpointID;

        if (id >= ENDPOINT_MAX) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                    ("MsgPend, Invalid Endpoint in look-ahead: %d \n",id));
            status = A_EPROTO;
            break;
        }
        /* try to allocate as many HTC RX packets indicated by the lookaheads
         * these packets are stored in the recvPkt queue */
        status = HIFDevAllocAndPrepareRxPackets(pDev,
                lookAheads,
                NumLookAheads,
                &recvPktQueue);
        if (A_FAILED(status)) {
            break;
        }
        totalFetched += HTC_PACKET_QUEUE_DEPTH(&recvPktQueue);

        /* we've got packet buffers for all we can currently fetch,
         * this count is not valid anymore  */
        NumLookAheads = 0;
        partialBundle = FALSE;

        /* now go fetch the list of HTC packets */
        while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
            pktsFetched = 0;
            if ((HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 1)) {
                /* there are enough packets to attempt a bundle transfer and recv bundling is allowed  */
                    status = HIFDevIssueRecvPacketBundle(pDev,
                            &recvPktQueue,
                            asyncProc ? NULL : &syncCompletedPktsQueue,
                            MailBoxIndex,
                            &pktsFetched,
                            partialBundle
#ifdef HIF_RX_THREAD
                            , &NumLookAheads
                            , lookAheads
#endif
                            , lookAhead_part2
                            );
                if (A_FAILED(status)) {
                    while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
                        adf_nbuf_t netbuf;

                        pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
                        if (pPacket == NULL)
                            break;
                        netbuf = (adf_nbuf_t) pPacket->pNetBufContext;
                        if (netbuf)
                            adf_nbuf_free(netbuf);
                    }
                    break;
                }

                if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) != 0) {
                    /* we couldn't fetch all packets at one time, this creates a broken
                     * bundle  */
                    partialBundle = TRUE;
                }
                if (pktsFetched)
                {
                    HTC_TARGET *target = NULL;
                    target = (HTC_TARGET *)pDev->pTarget;

#ifdef HTC_EP_STAT_PROFILING
                    LOCK_HTC_RX(target);
                    INC_HTC_EP_STAT(&target->EndPoint[id],RxPacketsBundled,pktsFetched);
                    UNLOCK_HTC_RX(target);
#endif
                }

            }

            /* see if the previous operation fetched any packets using bundling */
            if (0 == pktsFetched) {
                /* dequeue one packet */
                pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
                if (pPacket == NULL)
                    break;
                pPacket->Completion = NULL;

                if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 0) {
                    /* lookaheads in all packets except the last one in the bundle must be ignored */
                    pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
                }
#if DEBUG_BUNDLE
                adf_os_print("Recv single packet, length %d.\n", pPacket->ActualLength);
#endif

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

                /* go fetch the packet */
                status = HIFDevRecvPacket(pDev, pPacket, pPacket->ActualLength, MailBoxIndex);
                if (A_FAILED(status)) {
                    while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
                        adf_nbuf_t netbuf;

                        pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
                        if (pPacket == NULL)
                            break;
                        netbuf = (adf_nbuf_t) pPacket->pNetBufContext;
                        if (netbuf)
                            adf_nbuf_free(netbuf);
                    }
                    break;
                }
                /* sent synchronously, queue this packet for synchronous completion */
#ifdef HIF_RX_THREAD
                NumLookAheads = 0;
                HIFDevPreprocessTrailer(pDev, pPacket, lookAheads,
                                        &NumLookAheads, lookAhead_part2);
                pPacket->BundlePktnum = 1;
                spin_lock_irqsave(&pDev->pRecvTask->rx_sync_completion_lock, flags);
                HTC_PACKET_ENQUEUE(&pDev->pRecvTask->rxSyncCompletionQueue, pPacket);
                spin_unlock_irqrestore(&pDev->pRecvTask->rx_sync_completion_lock, flags);
#else
                HTC_PACKET_ENQUEUE(&syncCompletedPktsQueue, pPacket);
#endif
            }
        }

        /* synchronous handling */
        if (pDev->DSRCanYield) {
            /* for the SYNC case, increment count that tracks when the DSR should yield */
            pDev->CurrentDSRRecvCount++;
        }

        /* in the sync case, all packet buffers are now filled,
         * we can process each packet, check lookaheads and then repeat */
#ifdef HIF_RX_THREAD
        up(&pDev->pRecvTask->sem_rx_completion);
#else
        /* unload sync completion queue */
        while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
            A_UINT8 pipeid;
            adf_nbuf_t netbuf;

            pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
            if (pPacket == NULL)
                break;

            NumLookAheads = 0;
            status = HIFDevProcessRecvHeader(pDev, pPacket, lookAheads,
                                             &NumLookAheads, TRUE, lookAhead_part2);
            if (A_FAILED(status)) {
                HTC_PACKET_ENQUEUE_TO_HEAD(&syncCompletedPktsQueue, pPacket);
                break;
            }

            netbuf = (adf_nbuf_t) pPacket->pNetBufContext;
            /* set data length */
            adf_nbuf_put_tail(netbuf, pPacket->ActualLength);

            if (pDev->hif_callbacks.rxCompletionHandler) {
                pipeid = HIFDevMapMailBoxToPipe(pDev, MailBoxIndex, TRUE);
                pDev->hif_callbacks.rxCompletionHandler(pDev->hif_callbacks.Context,
                        netbuf,
                        pipeid);
            }
        }
#endif
        if (A_FAILED(status)) {
            while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
                adf_nbuf_t netbuf;

                pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
                if (pPacket == NULL)
                    break;
                netbuf = (adf_nbuf_t) pPacket->pNetBufContext;
                if (netbuf)
                    adf_nbuf_free(netbuf);
            }
            break;
        }

        if (NumLookAheads == 0) {
            /* no more look aheads */
            break;
        }
        /* check whether other OS contexts have queued any WMI command/data for WLAN.
         * This check is needed only if WLAN Tx and Rx happens in same thread context */
        A_CHECK_DRV_TX();
    }
    if (pNumPktsFetched != NULL) {
        *pNumPktsFetched = totalFetched;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCRecvMessagePendingHandler \n"));
    return status;
}

static A_STATUS HIFDevServiceCPUInterrupt(HIF_SDIO_DEVICE *pDev)
{
    A_STATUS status;
    A_UINT8 cpu_int_status;
    A_UINT8 regBuffer[4];

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("CPU Interrupt\n"));
    if (pDev == NULL)
       return A_ERROR;

    cpu_int_status = pDev->IrqProcRegisters.cpu_int_status
            & pDev->IrqEnableRegisters.cpu_int_status_enable;
    A_ASSERT(cpu_int_status);
    AR_DEBUG_PRINTF( ATH_DEBUG_IRQ,
            ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", cpu_int_status));

    /* Clear the interrupt */
    pDev->IrqProcRegisters.cpu_int_status &= ~cpu_int_status; /* W1C */

    /* set up the register transfer buffer to hit the register 4 times , this is done
     * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
     * restrict bus transfer lengths to be a multiple of 4-bytes */

    /* set W1C value to clear the interrupt, this hits the register first */
    regBuffer[0] = cpu_int_status;
    /* the remaining 4 values are set to zero which have no-effect  */
    regBuffer[1] = 0;
    regBuffer[2] = 0;
    regBuffer[3] = 0;

    status = HIFReadWrite(pDev->HIFDevice,
            CPU_INT_STATUS_ADDRESS,
            regBuffer,
            4,
            HIF_WR_SYNC_BYTE_FIX,
            NULL);

    A_ASSERT(status == A_OK);

    /* The Interrupt sent to the Host is generated via bit0 of CPU INT register*/
    if (cpu_int_status & 0x1){
        if (pDev && pDev->hif_callbacks.fwEventHandler)
            /* It calls into HTC which propagates this to ol_target_failure() */
            pDev->hif_callbacks.fwEventHandler(pDev->hif_callbacks.Context,
                                               A_ERROR);
    }
    else
    AR_DEBUG_PRINTF( ATH_DEBUG_ERROR,
            ("%s: Unable to call fwEventHandler, invalid input arguments\n",__func__));

    return status;
}

static A_STATUS HIFDevServiceErrorInterrupt(HIF_SDIO_DEVICE *pDev)
{
    A_STATUS status;
    A_UINT8 error_int_status;
    A_UINT8 regBuffer[4];

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error Interrupt\n"));
    error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F;
    A_ASSERT(error_int_status);
    AR_DEBUG_PRINTF( ATH_DEBUG_IRQ,
            ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n", error_int_status));

    if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
        /* Wakeup */
        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error : Wakeup\n"));
    }

    if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
        /* Rx Underflow */
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Rx Underflow\n"));
    }

    if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
        /* Tx Overflow */
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Tx Overflow\n"));
    }

    /* Clear the interrupt */
    pDev->IrqProcRegisters.error_int_status &= ~error_int_status; /* W1C */

    /* set up the register transfer buffer to hit the register 4 times , this is done
     * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
     * restrict bus transfer lengths to be a multiple of 4-bytes */

    /* set W1C value to clear the interrupt, this hits the register first */
    regBuffer[0] = error_int_status;
    /* the remaining 4 values are set to zero which have no-effect  */
    regBuffer[1] = 0;
    regBuffer[2] = 0;
    regBuffer[3] = 0;

    status = HIFReadWrite(pDev->HIFDevice,
            ERROR_INT_STATUS_ADDRESS,
            regBuffer,
            4,
            HIF_WR_SYNC_BYTE_FIX,
            NULL);

    A_ASSERT(status == A_OK);
    return status;
}

static A_STATUS HIFDevServiceDebugInterrupt(HIF_SDIO_DEVICE *pDev)
{
    A_UINT32 dummy;
    A_STATUS status;

    /* Send a target failure event to the application */
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n"));

    /* clear the interrupt , the debug error interrupt is
     * counter 0 */
    /* read counter to clear interrupt */
    status = HIFReadWrite(pDev->HIFDevice,
            COUNT_DEC_ADDRESS,
            (A_UINT8 *) &dummy,
            4,
            HIF_RD_SYNC_BYTE_INC,
            NULL);

    A_ASSERT(status == A_OK);
    return status;
}

static A_STATUS HIFDevServiceCounterInterrupt(HIF_SDIO_DEVICE *pDev)
{
    A_UINT8 counter_int_status;

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n"));

    counter_int_status = pDev->IrqProcRegisters.counter_int_status
            & pDev->IrqEnableRegisters.counter_int_status_enable;

    AR_DEBUG_PRINTF( ATH_DEBUG_IRQ,
            ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", counter_int_status));

    /* Check if the debug interrupt is pending
     * NOTE: other modules like GMBOX may use the counter interrupt for
     * credit flow control on other counters, we only need to check for the debug assertion
     * counter interrupt */
    if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
        return HIFDevServiceDebugInterrupt(pDev);
    }

    return A_OK;
}

/* process pending interrupts synchronously */
static A_STATUS HIFDevProcessPendingIRQs(HIF_SDIO_DEVICE *pDev, A_BOOL *pDone,
        A_BOOL *pASyncProcessing)
{
    A_STATUS status = A_OK;
    A_UINT8 host_int_status = 0;
    A_UINT32 lookAhead[MAILBOX_USED_COUNT];
    A_UINT32 lookAhead_part2[MAILBOX_USED_COUNT];
    int i;

    A_MEMZERO(&lookAhead, sizeof(lookAhead));
    A_MEMZERO(&lookAhead_part2, sizeof(lookAhead_part2));
    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
            ("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev));

    /*** NOTE: the HIF implementation guarantees that the context of this call allows
     *         us to perform SYNCHRONOUS I/O, that is we can block, sleep or call any API that
     *         can block or switch thread/task ontexts.
     *         This is a fully schedulable context.
     * */
    do {

        if (pDev->IrqEnableRegisters.int_status_enable == 0) {
            /* interrupt enables have been cleared, do not try to process any pending interrupts that
             * may result in more bus transactions.  The target may be unresponsive at this
             * point. */
            break;
        }

#ifdef HIF_SYNC_READ
        status = HIFSyncRead(pDev->HIFDevice,
                    HOST_INT_STATUS_ADDRESS,
                    (A_UINT8 *) &pDev->IrqProcRegisters,
                    sizeof(pDev->IrqProcRegisters),
                    HIF_RD_SYNC_BYTE_INC,
                    NULL);
#else
        status = HIFReadWrite(pDev->HIFDevice,
                    HOST_INT_STATUS_ADDRESS,
                    (A_UINT8 *) &pDev->IrqProcRegisters,
                    sizeof(pDev->IrqProcRegisters),
                    HIF_RD_SYNC_BYTE_INC,
                    NULL);
#endif

        if (A_FAILED(status)) {
            break;
        }

        if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) {
            HIFDevDumpRegisters(pDev,
                    &pDev->IrqProcRegisters,
                    &pDev->IrqEnableRegisters,
                    &pDev->MailBoxCounterRegisters);
        }

        /* Update only those registers that are enabled */
        host_int_status = pDev->IrqProcRegisters.host_int_status
                & pDev->IrqEnableRegisters.int_status_enable;

        /* only look at mailbox status if the HIF layer did not provide this function,
         * on some HIF interfaces reading the RX lookahead is not valid to do */
        for (i = 0; i < MAILBOX_USED_COUNT; i++) {
            lookAhead[i] = 0;
            if (host_int_status & (1 << i)) {
                /* mask out pending mailbox value, we use "lookAhead" as the real flag for
                 * mailbox processing below */
                host_int_status &= ~(1 << i);
                if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << i)) {
                    /* mailbox has a message and the look ahead is valid */
                    lookAhead[i] = pDev->IrqProcRegisters.rx_lookahead[MAILBOX_LOOKAHEAD_SIZE_IN_WORD*i];
                    lookAhead_part2[i] = pDev->IrqProcRegisters.rx_lookahead[MAILBOX_LOOKAHEAD_SIZE_IN_WORD*i + 1];
                }
            }
        } /*end of for loop*/
#ifdef HIF_RX_THREAD
        if (((HTC_FRAME_HDR *) &lookAhead[0])->EndpointID >= ENDPOINT_MAX) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Endpoint id in register invalid"
                            " %d\n", ((HTC_FRAME_HDR *) &lookAhead[0])->EndpointID));
        }
#endif
    } while (FALSE);

    do {
        A_BOOL bLookAheadValid = FALSE;
        /* did the interrupt status fetches succeed? */
        if (A_FAILED(status)) {
            break;
        }

        for (i = 0; i < MAILBOX_USED_COUNT; i++) {
            if (lookAhead[i] != 0) {
                bLookAheadValid = TRUE;
                break;
            }
        }

        if ((0 == host_int_status) && !bLookAheadValid) {
            /* nothing to process, the caller can use this to break out of a loop */
            *pDone = TRUE;
            break;
        }

        if (bLookAheadValid) {
            for (i = 0; i < MAILBOX_USED_COUNT; i++) {
                int fetched = 0;
                if (lookAhead[i] == 0) {
                    continue;
                }
                AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
                        ("Pending mailbox[%d] message, LookAhead: 0x%X\n", i, lookAhead[i]));
                /* Mailbox Interrupt, the HTC layer may issue async requests to empty the
                 * mailbox...
                 * When emptying the recv mailbox we use the async handler above called from the
                 * completion routine of the callers read request. This can improve performance
                 * by reducing context switching when we rapidly pull packets */
                status = HIFDevRecvMessagePendingHandler(pDev,
                        i,
                        &lookAhead[i],
                        1,
                        pASyncProcessing,
                        &fetched,
                        lookAhead_part2);
                if (A_FAILED(status)) {
                    break;
                }

                if (!fetched) {
                    /* HTC could not pull any messages out due to lack of resources */
                    /* force DSR handler to ack the interrupt */
                    *pASyncProcessing = FALSE;
                    pDev->RecheckIRQStatusCnt = 0;
                }
            }
        }

        /* now handle the rest of them */
        AR_DEBUG_PRINTF( ATH_DEBUG_IRQ,
                (" Valid interrupt source(s) for OTHER interrupts: 0x%x\n", host_int_status));

        if (HOST_INT_STATUS_CPU_GET(host_int_status)) {
            /* CPU Interrupt */
            status = HIFDevServiceCPUInterrupt(pDev);
            if (A_FAILED(status)) {
                break;
            }
        }

        if (HOST_INT_STATUS_ERROR_GET(host_int_status)) {
            /* Error Interrupt */
            status = HIFDevServiceErrorInterrupt(pDev);
            if (A_FAILED(status)) {
                break;
            }
        }

        if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) {
            /* Counter Interrupt */
            status = HIFDevServiceCounterInterrupt(pDev);
            if (A_FAILED(status)) {
                break;
            }
        }

    } while (FALSE);

    /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
     * the target, if upper layers determine that we are in a low-throughput mode, we can
     * rely on taking another interrupt rather than re-checking the status registers which can
     * re-wake the target.
     *
     * NOTE : for host interfaces that use the special GetPendingEventsFunc, this optimization cannot
     * be used due to possible side-effects.  For example, SPI requires the host to drain all
     * messages from the mailbox before exiting the ISR routine. */
    if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
                ("Bypassing IRQ Status re-check, forcing done \n"));
        *pDone = TRUE;
    }

    AR_DEBUG_PRINTF( ATH_DEBUG_IRQ,
            ("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n", *pDone, *pASyncProcessing, status));

    return status;
}

#define DEV_CHECK_RECV_YIELD(pDev) \
            ((pDev)->CurrentDSRRecvCount >= (pDev)->HifIRQYieldParams.RecvPacketYieldCount)

/* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/
A_STATUS HIFDevDsrHandler(void *context)
{
    HIF_SDIO_DEVICE *pDev = (HIF_SDIO_DEVICE *) context;
    A_STATUS status = A_OK;
    A_BOOL done = FALSE;
    A_BOOL asyncProc = FALSE;

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
            ("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned long)pDev));

    /* reset the recv counter that tracks when we need to yield from the DSR */
    pDev->CurrentDSRRecvCount = 0;
    /* reset counter used to flag a re-scan of IRQ status registers on the target */
    pDev->RecheckIRQStatusCnt = 0;

    while (!done) {
        status = HIFDevProcessPendingIRQs(pDev, &done, &asyncProc);
        if (A_FAILED(status)) {
            break;
        }

        if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
            /* the HIF layer does not allow async IRQ processing, override the asyncProc flag */
            asyncProc = FALSE;
            /* this will cause us to re-enter ProcessPendingIRQ() and re-read interrupt status registers.
             * this has a nice side effect of blocking us until all async read requests are completed.
             * This behavior is required on some HIF implementations that do not allow ASYNC
             * processing in interrupt handlers (like Windows CE) */

            if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) {
                /* ProcessPendingIRQs() pulled enough recv messages to satisfy the yield count, stop
                 * checking for more messages and return */
                break;
            }
        }

        if (asyncProc) {
            /* the function performed some async I/O for performance, we
             need to exit the ISR immediately, the check below will prevent the interrupt from being
             Ack'd while we handle it asynchronously */
            break;
        }

    }

    if (A_SUCCESS(status) && !asyncProc) {
        /* Ack the interrupt only if :
         *  1. we did not get any errors in processing interrupts
         *  2. there are no outstanding async processing requests */
        if (pDev->DSRCanYield) {
            /* if the DSR can yield do not ACK the interrupt, there could be more pending messages.
             * The HIF layer must ACK the interrupt on behalf of HTC */
            AR_DEBUG_PRINTF( ATH_DEBUG_IRQ,
                    (" Yield in effect (cur RX count: %d) \n", pDev->CurrentDSRRecvCount));
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
                    (" Acking interrupt from DevDsrHandler \n"));
            HIFAckInterrupt(pDev->HIFDevice);
        }
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevDsrHandler \n"));
    return status;
}

