示例#1
0
文件: htc_send.c 项目: KHATEEBNSIT/AP
A_BOOL
HTC_busy(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Ep, a_uint32_t nPkts)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    A_BOOL busy_flag;
    HTC_ENDPOINT *pEndpoint;

	if (Ep >= ENDPOINT_MAX) {
		adf_os_print("Ep %u is invalid!\n", Ep);
		adf_os_assert(0);
	}

	pEndpoint = &target->EndPoint[Ep];

    LOCK_HTC_TX(target);
    
    if (pEndpoint->TxBufCnt >= nPkts) {
        busy_flag = TRUE;
    }
    else {
        busy_flag = FALSE;
    }
    
    UNLOCK_HTC_TX(target);

    return busy_flag;
}
示例#2
0
文件: htc_send.c 项目: KHATEEBNSIT/AP
A_STATUS HTCTxEnqueuePkts(HTC_TARGET *target, 
                               HTC_ENDPOINT *pEndpoint, 
                                 adf_nbuf_t hdr_buf,
                                 adf_nbuf_t buf)
{
    //a_uint32_t i;
    A_STATUS status = A_OK;

    LOCK_HTC_TX(target);

    if (pEndpoint->TxBufCnt >= HTC_TX_QUEUE_SIZE) {
        UNLOCK_HTC_TX(target);
        //adf_os_print("HTC Tx queue is full!\n");
        return A_NO_RESOURCE;
    }

    pEndpoint->HtcTxQueue[pEndpoint->TxQTail].hdr_buf = hdr_buf;
    if (hdr_buf == ADF_NBUF_NULL) {
        pEndpoint->HtcTxQueue[pEndpoint->TxQTail].hdr_bufLen = 0;
    }
    else {
        pEndpoint->HtcTxQueue[pEndpoint->TxQTail].hdr_bufLen = adf_nbuf_len(hdr_buf);
    }
    pEndpoint->HtcTxQueue[pEndpoint->TxQTail].buf = buf;
    pEndpoint->HtcTxQueue[pEndpoint->TxQTail].bufLen = adf_nbuf_len(buf);

    pEndpoint->TxQTail = (pEndpoint->TxQTail + 1) % HTC_TX_QUEUE_SIZE;
    pEndpoint->TxBufCnt += 1;
    
    UNLOCK_HTC_TX(target);

    return (status? A_ERROR : A_OK);
}
示例#3
0
文件: htc.c 项目: NemProjects/WLAN
void HTCDumpCreditStates(HTC_HANDLE HTCHandle)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);

    LOCK_HTC_TX(target);

    DumpCreditDistStates(target);

    UNLOCK_HTC_TX(target);
}
示例#4
0
文件: htc_send.c 项目: KHATEEBNSIT/AP
a_uint16_t HTCGetTxBufCnt(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint)
{
    a_uint16_t TxBufCnt;

    LOCK_HTC_TX(target);
    TxBufCnt = pEndpoint->TxBufCnt;
    UNLOCK_HTC_TX(target);

    return TxBufCnt;
}
示例#5
0
A_BOOL htc_get_endpoint_statistics(HTC_HANDLE HTCHandle,
				   HTC_ENDPOINT_ID Endpoint,
				   HTC_ENDPOINT_STAT_ACTION Action,
				   HTC_ENDPOINT_STATS *pStats)
{
#ifdef HTC_EP_STAT_PROFILING
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	A_BOOL clearStats = false;
	A_BOOL sample = false;

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

	A_ASSERT(Endpoint < ENDPOINT_MAX);

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

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

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

	UNLOCK_HTC_RX(target);
	UNLOCK_HTC_TX(target);

	return true;
#else
	return false;
#endif
}
示例#6
0
文件: htc_send.c 项目: KHATEEBNSIT/AP
A_STATUS HTCReclaimCredits(HTC_TARGET *target,
                           a_uint32_t msglen,
                           HTC_ENDPOINT *pEndpoint)
{
    a_uint32_t creditsRequired, remainder;

    /* figure out how many credits this message requires */
    creditsRequired = (msglen / target->TargetCreditSize);
    remainder = (msglen % target->TargetCreditSize);

    if (remainder) {
        creditsRequired++;
    }

    LOCK_HTC_TX(target);

    pEndpoint->CreditDist.TxCredits += creditsRequired;

    UNLOCK_HTC_TX(target);

    return HIF_OK;
}
示例#7
0
文件: htc_send.c 项目: KHATEEBNSIT/AP
hif_status_t HTCTxCompletionHandler(void *Context, adf_nbuf_t netbuf)
{
    HTC_TARGET *target = (HTC_TARGET *)Context;
    //adf_os_handle_t os_hdl = target->os_handle;
    a_uint8_t *netdata;
    a_uint32_t netlen;
    HTC_FRAME_HDR *HtcHdr;
    a_uint8_t EpID;
    HTC_ENDPOINT *pEndpoint;
#ifndef HTC_HOST_CREDIT_DIST
    a_int32_t i;
#endif
    
    adf_nbuf_peek_header(netbuf, &netdata, &netlen);

    HtcHdr = (HTC_FRAME_HDR *)netdata;

    EpID = HtcHdr->EndpointID;
    pEndpoint = &target->EndPoint[EpID];

    if (EpID == ENDPOINT0) {
        adf_nbuf_free(netbuf);
    }
    else {
        /* gather tx completion counts */
        //HTC_AGGRNUM_REC *pAggrNumRec;

        //LOCK_HTC_TX(target);
        //pAggrNumRec = HTC_GET_REC_AT_HEAD(&pEndpoint->AggrNumRecQueue);
        
        //aggrNum = pAggrNumRec->AggrNum;
        //UNLOCK_HTC_TX(target);

        //if ((++pEndpoint->CompletedTxCnt) == aggrNum) {
            
            //pEndpoint->CompletedTxCnt = 0;

#if 0
            LOCK_HTC_TX(target);
            
            /* Dequeue from endpoint and then enqueue to target */
            pAggrNumRec = HTC_AGGRNUMREC_DEQUEUE(&pEndpoint->AggrNumRecQueue);
            HTC_AGGRNUMREC_ENQUEUE(&target->FreeAggrNumRecQueue, pAggrNumRec);
            
            UNLOCK_HTC_TX(target);
#endif

            /* remove HTC header */
            adf_nbuf_pull_head(netbuf, HTC_HDR_LENGTH);

            #if 1    /* freeing the net buffer instead of handing this buffer to upper layer driver */
            /* nofity upper layer */            
            if (pEndpoint->EpCallBacks.EpTxComplete) {
                /* give the packet to the upper layer */
                pEndpoint->EpCallBacks.EpTxComplete(/*dev*/pEndpoint->EpCallBacks.pContext, netbuf, EpID/*aggrNum*/);
            }
            else {
                adf_nbuf_free(netbuf);
            }
            #else
            adf_nbuf_free(netbuf);
            #endif
        //}

    }

#ifndef HTC_HOST_CREDIT_DIST
    /* Check whether there is any pending buffer needed */
    /* to be sent */
    if (pEndpoint->UL_PipeID == 1) {
        if (HTCNeedReschedule(target, pEndpoint) == A_OK) {
            for (i = ENDPOINT_MAX - 1; i >= 0; i--) {
                pEndpoint = &target->EndPoint[i];
                
                if (HTCGetTxBufCnt(target, pEndpoint) > 0)  {
                        HTCTrySend(target, NULL, ADF_NBUF_NULL, ADF_NBUF_NULL);
                        break;
                }
            }
        }
    }
#endif    
    
    return HIF_OK;
}
示例#8
0
文件: htc_send.c 项目: KHATEEBNSIT/AP
/* process credit reports and call distribution function */
void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt0, a_uint32_t RecLen, HTC_ENDPOINT_ID FromEndpoint)
{
    a_uint32_t i;
    a_uint32_t NumEntries;

#ifdef HTC_HOST_CREDIT_DIST
    a_uint32_t totalCredits = 0;
    a_uint8_t doDist = FALSE;
    HTC_ENDPOINT *pEndpoint;

    a_uint16_t seq_diff;
    a_uint16_t tgt_seq;
#endif
    HTC_CREDIT_REPORT_1_1 *pRpt = (HTC_CREDIT_REPORT_1_1 *)pRpt0 ;
    

    NumEntries = RecLen / (sizeof(HTC_CREDIT_REPORT_1_1)) ;
    /* lock out TX while we update credits */
    LOCK_HTC_TX(target);

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

        if (pRpt->EndpointID >= ENDPOINT_MAX) {
            adf_os_assert(0);
            break;
        }
#ifdef HTC_HOST_CREDIT_DIST
        pEndpoint = &target->EndPoint[pRpt->EndpointID];

        tgt_seq =  adf_os_ntohs(pRpt->TgtCreditSeqNo);
        if (ENDPOINT0 == pRpt->EndpointID) {
            /* always give endpoint 0 credits back */
            seq_diff =  (tgt_seq - pEndpoint->LastCreditSeq)  & (HTC_SEQ_MAX -1);

            pEndpoint->CreditDist.TxCredits += seq_diff;
            pEndpoint->LastCreditSeq = tgt_seq;

        }
        else {
            /* for all other endpoints, update credits to distribute, the distribution function
             * will handle giving out credits back to the endpoints */

#ifdef MAGPIE_HIF_GMAC
            if ( pRpt->EndpointID == 6 ) 
                OS_SET_TIMER(&host_seek_credit_timer, 1000);
#endif            
            
            seq_diff =  (tgt_seq - pEndpoint->LastCreditSeq)  & (HTC_SEQ_MAX -1);

            pEndpoint->CreditDist.TxCreditsToDist += seq_diff;
            pEndpoint->LastCreditSeq = tgt_seq;
            /* flag that we have to do the distribution */
            doDist = TRUE;
        }

        totalCredits += seq_diff;
#endif
        
    }
#ifdef HTC_HOST_CREDIT_DIST
    if (doDist) {
        /* this was a credit return based on a completed send operations
         * note, this is done with the lock held */       
        DO_DISTRIBUTION(target,
                        HTC_CREDIT_DIST_SEND_COMPLETE,
                        "Send Complete",
                        target->EpCreditDistributionListHead->pNext);        
    }
#endif
    UNLOCK_HTC_TX(target);
    
}
示例#9
0
文件: htc_send.c 项目: KHATEEBNSIT/AP
A_STATUS HTCSendPkt(HTC_HANDLE hHTC,
                    adf_nbuf_t hdr_buf,
                    adf_nbuf_t buf,
                    HTC_ENDPOINT_ID Ep)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(hHTC);
    A_STATUS status = A_OK;
    HTC_ENDPOINT *pEndpoint;

#ifndef ATH_HTC_TX_SCHED
    do {
	    if (Ep >= ENDPOINT_MAX) {
            adf_os_print("Ep %u is invalid!\n", Ep);
            if (hdr_buf) {
                adf_nbuf_free(hdr_buf);
            }
            if (buf) {
                adf_nbuf_free(buf);
            }
		    status = A_EPROTO;
		    break;
	    }

	    pEndpoint = &target->EndPoint[Ep];

#if 0
        LOCK_HTC_TX(target);
        /* record number of buffers in corresponding endpoint */
        if ((pAggrNumRec = HTC_AGGRNUMREC_DEQUEUE(&target->FreeAggrNumRecQueue)) == NULL) {
            adf_os_print("%s no more free aggr record\n", __FUNCTION__);
            status = A_NO_RESOURCE;
            UNLOCK_HTC_TX(target);
            break;
        }
        pAggrNumRec->AggrNum = num;
        pAggrNumRec->bufArray = bufArray;

        /* buffers were supplied to be queued */
        HTC_AGGRNUMREC_ENQUEUE(&pEndpoint->AggrNumRecQueue, pAggrNumRec);
        UNLOCK_HTC_TX(target);
#endif

        status = HTCTrySend(target, pEndpoint, hdr_buf, buf);

    //    adf_os_print("return value of HTCTrySend: %u\n", status);

    } while(FALSE);
#else
	a_uint16_t payloadLen;
    a_uint8_t SendFlags = 0;

    pEndpoint = &target->EndPoint[Ep];
    if ( HIFGetFreeQueueNumber(target->hif_dev, pEndpoint->UL_PipeID) == 0 )
            return -1 ;

    if(hdr_buf != NULL)
        payloadLen = (a_uint16_t) (adf_nbuf_len(hdr_buf) + adf_nbuf_len(buf));
    else
        payloadLen = (a_uint16_t) adf_nbuf_len(buf)  ;

#ifdef HTC_HOST_CREDIT_DIST
    /* check if credits are enough for sending this packet */
#ifdef WMI_RETRY
    if((Ep != 1 ) && (Ep != 2)) 
#endif
    {
        status = HTCCheckCredits(target, HTC_HDR_LENGTH + payloadLen, pEndpoint, &SendFlags);
        if (A_FAILED(status)) {
            //adf_os_print("credits are not enough for sending the message!\n");
            return status;
        }
    }
#endif
    status = HTCIssueSend(target, hdr_buf, buf, SendFlags, payloadLen, Ep);

    if (A_FAILED(status)) {
        HTCReclaimCredits(target, HTC_HDR_LENGTH + payloadLen, pEndpoint);
        return -1 ;
    }

#endif
    return status;
}
示例#10
0
文件: htc_send.c 项目: KHATEEBNSIT/AP
A_STATUS HTCCheckCredits(HTC_TARGET *target,
                         a_uint32_t msglen,
                         HTC_ENDPOINT *pEndpoint,
                         a_uint8_t *pSendFlags)
{
    a_uint32_t creditsRequired, remainder;

    /* figure out how many credits this message requires */
    creditsRequired = (msglen / target->TargetCreditSize);
    remainder = (msglen % target->TargetCreditSize);

    if (remainder) {
        creditsRequired++;
    }

    LOCK_HTC_TX(target);

    //adf_os_print("creditsRequired: %u, msglen: %u, target->TargetCreditSize: %u, pEndpoint->CreditDist.TxCredits: %u\n", creditsRequired, msglen, target->TargetCreditSize, pEndpoint->CreditDist.TxCredits);

    /* not enough credits */
    if (pEndpoint->CreditDist.TxCredits < creditsRequired) {

        /* set how many credits we need  */
        pEndpoint->CreditDist.TxCreditsSeek = creditsRequired - pEndpoint->CreditDist.TxCredits;

        DO_DISTRIBUTION(target,
                        HTC_CREDIT_DIST_SEEK_CREDITS,
                        "Seek Credits",
                        &pEndpoint->CreditDist);

        pEndpoint->CreditDist.TxCreditsSeek = 0;

        if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
            /* still not enough credits to send, leave packet in the queue */
            UNLOCK_HTC_TX(target);
            //adf_os_print("htc: credit is unavailable: %u, pEndpoint->CreditDist.TxCredits: %u, creditsRequired: %u\n", A_CREDIT_UNAVAILABLE, pEndpoint->CreditDist.TxCredits, creditsRequired);
            return A_CREDIT_UNAVAILABLE;
        }
    }

    pEndpoint->CreditDist.TxCredits -= creditsRequired;
    /* check if we need credits back from the target */
    if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
        /* we are getting low on credits, see if we can ask for more from the distribution function */
        pEndpoint->CreditDist.TxCreditsSeek = pEndpoint->CreditDist.TxCreditsPerMaxMsg - pEndpoint->CreditDist.TxCredits;

        DO_DISTRIBUTION(target,
                        HTC_CREDIT_DIST_SEEK_CREDITS,
                        "Seek Credits",
                        &pEndpoint->CreditDist);

        pEndpoint->CreditDist.TxCreditsSeek = 0;

        if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
            /* tell the target we need credits ASAP! */
            *pSendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
            //adf_os_print("SendFlags: %u\n", *pSendFlags);
        }
    }

    UNLOCK_HTC_TX(target);
    return A_OK;
}
示例#11
0
文件: htc_send.c 项目: KHATEEBNSIT/AP
A_STATUS HTCTrySend(HTC_TARGET      *target, 
                    HTC_ENDPOINT    *pEndpoint, 
                    adf_nbuf_t      hdr_buf,
                    adf_nbuf_t      buf)
{
    a_uint8_t SendFlags = 0;
    a_uint16_t payloadLen;
    a_uint8_t EpID;
    A_STATUS status = A_OK;
#if 0 
    a_uint32_t creditsRequired, remainder;
#endif
    a_int32_t i;
    
    if ( (pEndpoint) 
         && (buf != ADF_NBUF_NULL) ) 
    {
        /* packet was supplied to be queued */
        status = HTCTxEnqueuePkts(target, pEndpoint, hdr_buf, buf);

        if (A_FAILED(status)) {
            if (buf)     { adf_nbuf_free(buf);     }
            if (hdr_buf) { adf_nbuf_free(hdr_buf); }
            //adf_os_print("%s: Not enough queue spaces for enqueuing, epid = %d, enqueue fail cnt = %d\n", 
            //              __func__, 
            //              pEndpoint->CreditDist.Endpoint, ++(pEndpoint->stat_enqfail));
        }
    }

    /* now drain the TX queue for transmission as long as we have enough credits */

    LOCK_HTC_TX(target);

    for (i = ENDPOINT_MAX - 1; i >= 0; i--) {
        a_uint32_t availableTxCnt = 0xFFFFFFFF;
        a_uint8_t  isDataService = 0;

        pEndpoint = &target->EndPoint[i];
        EpID = pEndpoint->CreditDist.Endpoint;

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

        /* calculate available tx count base on the de-queue level */
        if ((pEndpoint->ServiceID == WMI_DATA_BE_SVC)
            || (pEndpoint->ServiceID == WMI_DATA_BK_SVC)
            || (pEndpoint->ServiceID == WMI_DATA_VI_SVC)
            || (pEndpoint->ServiceID == WMI_DATA_VO_SVC)) {
            isDataService = 1;
            if (pEndpoint->tqi_dqlevel < 4) {
                availableTxCnt  = 4- pEndpoint->tqi_dqlevel;
            } else {
                availableTxCnt = 1;
            }
            //adf_os_print("%s: epid = %d, i = %d, dqlevel = %d, txcnt = %d\n", __FUNCTION__, EpID, i, pEndpoint->tqi_dqlevel, availableTxCnt);
        }

        while (availableTxCnt-- > 0) {
            adf_nbuf_t tmpbuf, tmp_hdr_buf;
            a_uint16_t tmplen, tmp_hdr_len;
            a_uint16_t freeQNum, maxQNum, toNext;
            
            if (pEndpoint->TxBufCnt == 0) {
                break;
            }
            
            if ( (freeQNum = HIFGetFreeQueueNumber(target->hif_dev, pEndpoint->UL_PipeID)) == 0 ) {
                //adf_os_print("%s: USB TxQ full, epid = %d, pipe id = %d, count = %d\n", 
                //              __func__, EpID, pEndpoint->UL_PipeID, ++(pEndpoint->stat_usbqfull));
                break;
            }

            if (isDataService) {
                toNext = 0;
                maxQNum = HIFGetMaxQueueNumber(target->hif_dev, pEndpoint->UL_PipeID);
                //adf_os_print("%s: epid = %d, freeQNum = %d, maxQNum = %d, availableTxCnt = %d\n", __FUNCTION__, EpID, freeQNum, maxQNum, availableTxCnt);
                switch (pEndpoint->tqi_dqlevel) {
                case 0:
                    if (freeQNum == 0) {toNext = 1;}
                        break;
                case 1:
                    if (freeQNum <= maxQNum/2) {toNext = 1;}        //4/8
                        break;
                case 2:
                    if (freeQNum <= (maxQNum*5)/8) {toNext = 1;}    //5/8
                        break;
                case 3:
                default:
                    if (freeQNum <= (maxQNum*3)/4) {toNext = 1;}    //6/8
                        break;
                }

                if (toNext == 1) {
                //    adf_os_print("%s: To Next Endpoint, epid = %d, freeQNum = %d, maxQNum = %d\n", __FUNCTION__, EpID, freeQNum, maxQNum);
                    break;
                }
            }

            /* get packet at head, but don't remove it */
            tmp_hdr_buf = pEndpoint->HtcTxQueue[pEndpoint->TxQHead].hdr_buf;
            tmp_hdr_len = pEndpoint->HtcTxQueue[pEndpoint->TxQHead].hdr_bufLen;
            tmpbuf = pEndpoint->HtcTxQueue[pEndpoint->TxQHead].buf;
            tmplen = pEndpoint->HtcTxQueue[pEndpoint->TxQHead].bufLen;

    #if 0 
    
            /* figure out how many credits this message requires */
            creditsRequired = (tmplen + tmp_hdr_len + HTC_HDR_LENGTH) / target->TargetCreditSize;
            remainder = (tmplen + tmp_hdr_len + HTC_HDR_LENGTH) % target->TargetCreditSize;
    
            if (remainder) {
                creditsRequired++;
            }
    
            adf_os_print("creditsRequired: %u, tmplen + HTC_HDR_LENGTH: %u, target->TargetCreditSize: %u, pEndpoint->CreditDist.TxCredits: %u\n", creditsRequired, tmplen + HTC_HDR_LENGTH, target->TargetCreditSize, pEndpoint->CreditDist.TxCredits);
    
            /* not enough credits */
            if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
    
                /* set how many credits we need  */
                pEndpoint->CreditDist.TxCreditsSeek = creditsRequired - pEndpoint->CreditDist.TxCredits;
    
                DO_DISTRIBUTION(target,
                                HTC_CREDIT_DIST_SEEK_CREDITS,
                                "Seek Credits",
                                &pEndpoint->CreditDist);
    
                pEndpoint->CreditDist.TxCreditsSeek = 0;
    
                if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
                    /* still not enough credits to send, leave packet in the queue */
					status = A_CREDIT_UNAVAILABLE;                    
					break;
                }
            }
    
            pEndpoint->CreditDist.TxCredits -= creditsRequired;
    
            //adf_os_print("pEndpoint->CreditDist.TxCreditsPerMaxMsg: %u\n", pEndpoint->CreditDist.TxCreditsPerMaxMsg);
    
            /* check if we need credits back from the target */
            if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
                /* we are getting low on credits, see if we can ask for more from the distribution function */
                pEndpoint->CreditDist.TxCreditsSeek = pEndpoint->CreditDist.TxCreditsPerMaxMsg - pEndpoint->CreditDist.TxCredits;
    
                DO_DISTRIBUTION(target,
                                HTC_CREDIT_DIST_SEEK_CREDITS,
                                "Seek Credits",
                                &pEndpoint->CreditDist);
    
                pEndpoint->CreditDist.TxCreditsSeek = 0;
    
                if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
                    /* tell the target we need credits ASAP! */
                    SendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
                    adf_os_print("SendFlags: %u\n", SendFlags);
                }
    
    #endif   
    
                payloadLen = tmp_hdr_len + tmplen;
    
                /* now we can fully dequeue */
                pEndpoint->TxQHead = (pEndpoint->TxQHead + 1) % HTC_TX_QUEUE_SIZE;
                pEndpoint->TxBufCnt--;
    
                UNLOCK_HTC_TX(target);

                status = HTCIssueSend(target, tmp_hdr_buf, tmpbuf, SendFlags, payloadLen, EpID);

                LOCK_HTC_TX(target);

                if (A_FAILED(status)) {
                    adf_os_print("%s: Fail to send pkt to HIF, cnt = %d, usesendfail = %d\n", 
                           __func__, EpID, ++(pEndpoint->stat_usbsendfail));
#if 0
        			/* reclaim the credit due to failure to send */
            		HTCReclaimCredits(target, HTC_HDR_LENGTH + payloadLen, pEndpoint);
#endif        
                    if (tmpbuf)      { adf_nbuf_free(tmpbuf);      }
                    if (tmp_hdr_buf) { adf_nbuf_free(tmp_hdr_buf); }
                    break;
                }
    
    #if 0 
            }
    #endif
        }
    } /* for (i = ENDPOINT_MAX - 1; i >= 0; i--) */
    
    UNLOCK_HTC_TX(target);
#if 0 
       return status;
#else 
       return A_OK;
#endif  
}