Beispiel #1
0
void  HTCDestroy(HTC_HANDLE HTCHandle)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy ..  Destroying :0x%p \n",target));
    HTCCleanup(target);
    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n"));
}
Beispiel #2
0
void htc_dump_credit_states(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	HTC_ENDPOINT *pEndpoint;
	int i;

	for (i = 0; i < ENDPOINT_MAX; i++) {
		pEndpoint = &target->EndPoint[i];
		if (0 == pEndpoint->ServiceID) {
			continue;
		}
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				("--- EP : %d  ServiceID: 0x%X    --------------\n",
				 pEndpoint->Id, pEndpoint->ServiceID));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				(" TxCredits          : %d \n",
				 pEndpoint->TxCredits));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				(" TxCreditSize       : %d \n",
				 pEndpoint->TxCreditSize));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				(" TxCreditsPerMaxMsg : %d \n",
				 pEndpoint->TxCreditsPerMaxMsg));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				(" TxQueueDepth       : %d \n",
				 HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
				("----------------------------------------------------\n"));
	}
}
Beispiel #3
0
/*flush all queued buffers for surpriseremove case*/
void htc_flush_surprise_remove(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	int i;
	HTC_ENDPOINT *pEndpoint;
#ifdef RX_SG_SUPPORT
	cdf_nbuf_t netbuf;
	cdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
#endif

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_flush_surprise_remove \n"));

	/* cleanup endpoints */
	for (i = 0; i < ENDPOINT_MAX; i++) {
		pEndpoint = &target->EndPoint[i];
		htc_flush_rx_hold_queue(target, pEndpoint);
		htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
	}

	hif_flush_surprise_remove(target->hif_dev);

#ifdef RX_SG_SUPPORT
	LOCK_HTC_RX(target);
	while ((netbuf = cdf_nbuf_queue_remove(rx_sg_queue)) != NULL) {
		cdf_nbuf_free(netbuf);
	}
	RESET_RX_SG_CONFIG(target);
	UNLOCK_HTC_RX(target);
#endif

	reset_endpoint_states(target);

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_flush_surprise_remove \n"));
}
Beispiel #4
0
int HTCGetNumRecvBuffers(HTC_HANDLE      HTCHandle,
                         HTC_ENDPOINT_ID Endpoint)
{
    HTC_TARGET      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_ENDPOINT    *pEndpoint = &target->EndPoint[Endpoint];
    return HTC_PACKET_QUEUE_DEPTH(&pEndpoint->RxBufferHoldQueue);
}
Beispiel #5
0
A_STATUS HTCStart(HTC_HANDLE HTCHandle)
{
    adf_nbuf_t netbuf;
    A_STATUS   status = A_OK;
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_SETUP_COMPLETE_MSG *SetupComp;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));
    do {
         
        HTCConfigTargetHIFPipe(HTCHandle);

#ifdef HTC_HOST_CREDIT_DIST
        adf_os_assert(target->InitCredits != NULL);
        adf_os_assert(target->EpCreditDistributionListHead != NULL);
        adf_os_assert(target->EpCreditDistributionListHead->pNext != NULL);

        /* call init credits callback to do the distribution , 
         * NOTE: the first entry in the distribution list is ENDPOINT_0, so
         * we pass the start of the list after this one. */
        target->InitCredits(target->pCredDistContext, 
                            target->EpCreditDistributionListHead->pNext,
                            target->TargetCredits);

#if 1
        adf_os_timer_init(target->os_handle, &target->host_htc_credit_debug_timer, host_htc_credit_show, target);
        adf_os_timer_start(&target->host_htc_credit_debug_timer, 10000);
#endif
#endif

        /* allocate a buffer to send */
        //netbuf = adf_nbuf_alloc(anet, sizeof(HTC_SETUP_COMPLETE_MSG), HTC_HDR_LENGTH, 0);
        netbuf = adf_nbuf_alloc(50, HTC_HDR_LENGTH, 0);

        if (netbuf == ADF_NBUF_NULL) {
            status = A_NO_MEMORY;
            break;
        }

        /* assemble setup complete message */
        SetupComp = (HTC_SETUP_COMPLETE_MSG *)adf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_MSG));
        SetupComp->MessageID = adf_os_htons(HTC_MSG_SETUP_COMPLETE_ID);

        /* assemble the HTC header and send to HIF layer */
        status = HTCIssueSend(target, 
                              ADF_NBUF_NULL, 
                              netbuf, 
                              0, 
                              sizeof(HTC_SETUP_COMPLETE_MSG),
                              ENDPOINT0);
        
        if (A_FAILED(status)) {
            break;    
        }

    } while (FALSE);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
    return status;
}
Beispiel #6
0
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;
}
Beispiel #7
0
A_STATUS HTCTrySendAll(HTC_HANDLE hHTC)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(hHTC);

	HTCTrySend(target, NULL, ADF_NBUF_NULL, ADF_NBUF_NULL);

	return A_OK;
}
void HTCDisableRecv(HTC_HANDLE HTCHandle)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);

    if (!HTC_STOPPING(target)) {
            /* disable */
        DevStopRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
    }
}
Beispiel #9
0
A_STATUS HTCStart(HTC_HANDLE HTCHandle)
{
    adf_nbuf_t                 netbuf;
    A_STATUS                   status = A_OK;
    HTC_TARGET                 *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_SETUP_COMPLETE_EX_MSG  *pSetupComp;
    HTC_PACKET                 *pSendPacket;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));

    do {

        HTCConfigTargetHIFPipe(target);

            /* allocate a buffer to send */
        pSendPacket = HTCAllocControlTxPacket(target);
        if (NULL == pSendPacket) {
            AR_DEBUG_ASSERT(FALSE);
	        adf_os_print("%s: allocControlTxPacket failed\n",__func__);
            status = A_NO_MEMORY;
            break;
        }

        netbuf = (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket);
            /* assemble setup complete message */
        adf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
        pSetupComp = (HTC_SETUP_COMPLETE_EX_MSG *) adf_nbuf_data(netbuf);
        A_MEMZERO(pSetupComp,sizeof(HTC_SETUP_COMPLETE_EX_MSG));

        HTC_SET_FIELD(pSetupComp, HTC_SETUP_COMPLETE_EX_MSG,
                    MESSAGEID, HTC_MSG_SETUP_COMPLETE_EX_ID);

        //if (!htc_credit_flow) {
        if (0) {
            AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("HTC will not use TX credit flow control\n"));
            pSetupComp->SetupFlags |= HTC_SETUP_COMPLETE_FLAGS_DISABLE_TX_CREDIT_FLOW;
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("HTC using TX credit flow control\n"));
        }

        SET_HTC_PACKET_INFO_TX(pSendPacket,
                               NULL,
                               (A_UINT8 *)pSetupComp,
                               sizeof(HTC_SETUP_COMPLETE_EX_MSG),
                               ENDPOINT_0,
                               HTC_SERVICE_TX_PACKET_TAG);

        status = HTCSendPkt((HTC_HANDLE)target,pSendPacket);
        if (A_FAILED(status)) {
            break;
        }

    } while (FALSE);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
    return status;
}
Beispiel #10
0
void HTCDumpCreditStates(HTC_HANDLE HTCHandle)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);

    LOCK_HTC_TX(target);

    DumpCreditDistStates(target);

    UNLOCK_HTC_TX(target);
}
Beispiel #11
0
void htc_destroy(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
			("+htc_destroy ..  Destroying :0x%p\n", target));
	hif_stop(htc_get_hif_device(HTCHandle));
	if (target)
		htc_cleanup(target);
	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_destroy\n"));
}
Beispiel #12
0
A_STATUS HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue)
{
    HTC_TARGET      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_ENDPOINT    *pEndpoint;
    HTC_PACKET      *pFirstPacket;
    A_STATUS        status = A_OK;
    HTC_PACKET      *pPacket;

    pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);

    if (NULL == pFirstPacket) {
        A_ASSERT(FALSE);
        return A_EINVAL;
    }

    AR_DEBUG_ASSERT(pFirstPacket->Endpoint < ENDPOINT_MAX);

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
                    ("+- HTCAddReceivePktMultiple : endPointId: %d, cnt:%d, length: %d\n",
                    pFirstPacket->Endpoint,
                    HTC_PACKET_QUEUE_DEPTH(pPktQueue),
                    pFirstPacket->BufferLength));

    pEndpoint = &target->EndPoint[pFirstPacket->Endpoint];

    LOCK_HTC_RX(target);

    do {

        if (HTC_STOPPING(target)) {
            status = A_ERROR;
            break;
        }

            /* store receive packets */
        HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RxBufferHoldQueue,pPktQueue);

    } while (FALSE);

    UNLOCK_HTC_RX(target);

    if (A_FAILED(status)) {
            /* walk through queue and mark each one canceled */
        HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
            pPacket->Status = A_ECANCELED;
        } HTC_PACKET_QUEUE_ITERATE_END;

        DoRecvCompletion(pEndpoint,pPktQueue);
    }

    return status;
}
Beispiel #13
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
}
Beispiel #14
0
/**
 * htc_ipa_get_ce_resource() - get uc resource on lower layer
 * @htc_handle: htc context
 * @ce_sr_base_paddr: copyengine source ring base physical address
 * @ce_sr_ring_size: copyengine source ring size
 * @ce_reg_paddr: copyengine register physical address
 *
 * Return: None
 */
void htc_ipa_get_ce_resource(HTC_HANDLE htc_handle,
			     cdf_dma_addr_t *ce_sr_base_paddr,
			     uint32_t *ce_sr_ring_size,
			     cdf_dma_addr_t *ce_reg_paddr)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	if (target->hif_dev != NULL) {
		hif_ipa_get_ce_resource(target->hif_dev,
					ce_sr_base_paddr,
					ce_sr_ring_size, ce_reg_paddr);
	}
}
Beispiel #15
0
/* Makes a buffer available to the HTC module */
A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_ENDPOINT *pEndpoint;
    A_BOOL       unblockRecv = FALSE;
    A_STATUS     status = A_OK;

    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
                    ("+- HTCAddReceivePkt: endPointId: %d, buffer: 0x%X, length: %d\n",
                    pPacket->Endpoint, (A_UINT32)pPacket->pBuffer, pPacket->BufferLength));

    do {
        AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);

        pEndpoint = &target->EndPoint[pPacket->Endpoint];

        LOCK_HTC_RX(target);

        if (HTC_STOPPING(target)) {
            pPacket->Status = A_ECANCELED;
            status = A_ECANCELED;
            UNLOCK_HTC_RX(target);
            pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket);
            break;
        }

            /* store receive packet */
        HTC_PACKET_ENQUEUE(&pEndpoint->RxBuffers, pPacket);

            /* check if we are blocked waiting for a new buffer */
        if (target->HTCStateFlags & HTC_STATE_WAIT_BUFFERS) {
            if (target->EpWaitingForBuffers == pPacket->Endpoint) {
                AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" receiver was blocked on ep:%d, unblocking.. \n",
                    target->EpWaitingForBuffers));
                target->HTCStateFlags &= ~HTC_STATE_WAIT_BUFFERS;
                target->EpWaitingForBuffers = ENDPOINT_MAX;
                unblockRecv = TRUE;
            }
        }

        UNLOCK_HTC_RX(target);

        if (unblockRecv && !HTC_STOPPING(target)) {
                /* TODO : implement a buffer threshold count? */
            DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
        }

    } while (FALSE);

    return status;
}
Beispiel #16
0
A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle)
{
    A_STATUS    status = A_OK;
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    
    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%X) \n", (A_UINT32)HTCHandle));

    A_STATUS status = A_OK;
    /* a_status_t wait_status;*/
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);

    HIFStart(target->hif_dev);
    adf_os_print("[%s %d] Starting mutex waiting...\n",adf_os_function, __LINE__);

    adf_os_mutex_acquire(&target->htc_rdy_mutex);

    adf_os_print("[%s %d] Finish mutex waiting...\n",adf_os_function, __LINE__); 

    return status;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n"));

    return status;
}
Beispiel #17
0
void HTCTxComp(HTC_HANDLE hHTC,
               adf_nbuf_t buf,
               HTC_ENDPOINT_ID ep)
{
#ifdef __linux__
    HTC_ENDPOINT *pEndpoint;
    HTC_TARGET   *target = GET_HTC_TARGET_FROM_HANDLE(hHTC);

    pEndpoint = &target->EndPoint[ep];

    if (pEndpoint->EpCallBacks.EpTxComplete != NULL) {
        pEndpoint->EpCallBacks.EpTxComplete( pEndpoint->EpCallBacks.pContext, buf, ep);
    }
#endif
}
void HTCSetCreditDistribution(HTC_HANDLE               HTCHandle,
                              void                     *pCreditDistContext,
                              HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
                              HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
                              HTC_SERVICE_ID           ServicePriorityOrder[],
                              int                      ListLength)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    int i;
    int ep;

    if (CreditInitFunc != NULL) {
            /* caller has supplied their own distribution functions */
        target->InitCredits = CreditInitFunc;
        AR_DEBUG_ASSERT(CreditDistFunc != NULL);
        target->DistributeCredits = CreditDistFunc;
        target->pCredDistContext = pCreditDistContext;
    } else {
        /* caller wants HTC to do distribution */
        /* if caller wants service to handle distributions then
         * it must set both of these to NULL! */
        AR_DEBUG_ASSERT(CreditDistFunc == NULL);
        target->InitCredits = HTCDefaultCreditInit;
        target->DistributeCredits = HTCDefaultCreditDist;
        target->pCredDistContext = target;
    }

        /* always add HTC control endpoint first, we only expose the list after the
         * first one, this is added for TX queue checking */
    AddToEndpointDistList(target, &target->EndPoint[ENDPOINT_0].CreditDist);

        /* build the list of credit distribution structures in priority order
         * supplied by the caller, these will follow endpoint 0 */
    for (i = 0; i < ListLength; i++) {
            /* match services with endpoints and add the endpoints to the distribution list
             * in FIFO order */
        for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
            if (target->EndPoint[ep].ServiceID == ServicePriorityOrder[i]) {
                    /* queue this one to the list */
                AddToEndpointDistList(target, &target->EndPoint[ep].CreditDist);
                break;
            }
        }
        AR_DEBUG_ASSERT(ep < ENDPOINT_MAX);
    }

}
Beispiel #19
0
/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
void htc_stop(HTC_HANDLE HTCHandle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	int i;
	HTC_ENDPOINT *pEndpoint;
#ifdef RX_SG_SUPPORT
	cdf_nbuf_t netbuf;
	cdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
#endif

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_stop \n"));

	/* cleanup endpoints */
	for (i = 0; i < ENDPOINT_MAX; i++) {
		pEndpoint = &target->EndPoint[i];
		htc_flush_rx_hold_queue(target, pEndpoint);
		htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
		if (pEndpoint->ul_is_polled) {
			cdf_softirq_timer_cancel(&pEndpoint->ul_poll_timer);
			cdf_softirq_timer_free(&pEndpoint->ul_poll_timer);
		}
	}

	/* Note: htc_flush_endpoint_tx for all endpoints should be called before
	 * hif_stop - otherwise htc_tx_completion_handler called from
	 * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer,
	 * might queue the packet again to HIF Layer - which could cause tx
	 * buffer leak
	 */

	hif_stop(target->hif_dev);

#ifdef RX_SG_SUPPORT
	LOCK_HTC_RX(target);
	while ((netbuf = cdf_nbuf_queue_remove(rx_sg_queue)) != NULL) {
		cdf_nbuf_free(netbuf);
	}
	RESET_RX_SG_CONFIG(target);
	UNLOCK_HTC_RX(target);
#endif

	reset_endpoint_states(target);

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_stop \n"));
}
Beispiel #20
0
/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
void HTCStop(HTC_HANDLE HTCHandle)
{
    HTC_TARGET    *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    int           i;
    HTC_ENDPOINT  *pEndpoint;
#ifdef RX_SG_SUPPORT
    adf_nbuf_t netbuf;
    adf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
#endif

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n"));

        /* cleanup endpoints */
    for (i = 0; i < ENDPOINT_MAX; i++) {
        pEndpoint = &target->EndPoint[i];
        HTCFlushRxHoldQueue(target,pEndpoint);
        HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL);
    }

    /* Note: HTCFlushEndpointTX for all endpoints should be called before
     * HIFStop - otherwise HTCTxCompletionHandler called from
     * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer,
     * might queue the packet again to HIF Layer - which could cause tx
     * buffer leak
     */

    HIFStop(target->hif_dev);

#ifdef RX_SG_SUPPORT
    LOCK_HTC_RX(target);
    while ((netbuf = adf_nbuf_queue_remove(rx_sg_queue)) != NULL) {
        adf_nbuf_free(netbuf);
    }
    RESET_RX_SG_CONFIG(target);
    UNLOCK_HTC_RX(target);
#endif

    ResetEndpointStates(target);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n"));
}
Beispiel #21
0
/* cleanup the HTC instance */
static void HTCCleanup(HTC_TARGET *target)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);


    HIF_Cleanup(target->hif_dev);  /*Todo HIF should cleanup if any buffers are there*/

#ifdef HTC_HOST_CREDIT_DIST
    adf_os_timer_cancel(&target->host_htc_credit_debug_timer);
#endif

    /* release htc_rdy_mutex */
    adf_os_mutex_release(&target->htc_rdy_mutex);

    /* free our instance */
    adf_os_mem_free(target);
    /* TODO : other cleanup */

    /* free our instance */
    A_FREE(target);
}
Beispiel #22
0
/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
void HTCStop(HTC_HANDLE HTCHandle)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n"));

        /* mark that we are shutting down .. */
    target->HTCStateFlags |= HTC_STATE_STOPPING;

        /* Masking interrupts is a synchronous operation, when this function returns
         * all pending HIF I/O has completed, we can safely flush the queues */
    DevMaskInterrupts(&target->Device);

        /* flush all send packets */
    HTCFlushSendPkts(target);
        /* flush all recv buffers */
    HTCFlushRecvBuffers(target);

    ResetEndpointStates(target);
   
    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n"));
}
Beispiel #23
0
void HTCUnblockRecv(HTC_HANDLE HTCHandle)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    A_BOOL      unblockRecv = FALSE;

    LOCK_HTC_RX(target);

        /* check if we are blocked waiting for a new buffer */
    if (target->HTCStateFlags & HTC_STATE_WAIT_BUFFERS) {
        AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HTCUnblockRx : receiver was blocked on ep:%d, unblocking.. \n",
            target->EpWaitingForBuffers));
        target->HTCStateFlags &= ~HTC_STATE_WAIT_BUFFERS;
        target->EpWaitingForBuffers = ENDPOINT_MAX;
        unblockRecv = TRUE;
    }

    UNLOCK_HTC_RX(target);

    if (unblockRecv && !HTC_STOPPING(target)) {
            /* re-enable */
        DevEnableRecv(&target->Device,DEV_ENABLE_RECV_ASYNC);
    }
}
A_STATUS HTCConnectService(HTC_HANDLE               HTCHandle,
                           HTC_SERVICE_CONNECT_REQ  *pConnectReq,
                           HTC_SERVICE_CONNECT_RESP *pConnectResp)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    A_STATUS                            status = A_OK;
    HTC_PACKET                          *pRecvPacket = NULL;
    HTC_PACKET                          *pSendPacket = NULL;
    HTC_CONNECT_SERVICE_RESPONSE_MSG    *pResponseMsg;
    HTC_CONNECT_SERVICE_MSG             *pConnectMsg;
    HTC_ENDPOINT_ID                     assignedEndpoint = ENDPOINT_MAX;
    HTC_ENDPOINT                        *pEndpoint;
    unsigned int                        maxMsgSize = 0;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%X SvcID:0x%X \n",
               (A_UINT32)target, pConnectReq->ServiceID));

    do {

        AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0);

        if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) {
                /* special case for pseudo control service */
            assignedEndpoint = ENDPOINT_0;
            maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH;
        } else {
                /* allocate a packet to send to the target */
            pSendPacket = HTC_ALLOC_CONTROL_TX(target);

            if (NULL == pSendPacket) {
                AR_DEBUG_ASSERT(FALSE);
                status = A_NO_MEMORY;
                break;
            }
                /* assemble connect service message */
            pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)pSendPacket->pBuffer;
            AR_DEBUG_ASSERT(pConnectMsg != NULL);
            A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG));
            pConnectMsg->MessageID = HTC_MSG_CONNECT_SERVICE_ID;
            pConnectMsg->ServiceID = pConnectReq->ServiceID;
            pConnectMsg->ConnectionFlags = pConnectReq->ConnectionFlags;
                /* check caller if it wants to transfer meta data */
            if ((pConnectReq->pMetaData != NULL) &&
                (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
                    /* copy meta data into message buffer (after header ) */
                A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG),
                         pConnectReq->pMetaData,
                         pConnectReq->MetaDataLength);
                pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength;
            }

            SET_HTC_PACKET_INFO_TX(pSendPacket,
                                   NULL,
                                   (A_UINT8 *)pConnectMsg,
                                   sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg->ServiceMetaLength,
                                   ENDPOINT_0,
                                   HTC_SERVICE_TX_PACKET_TAG);

                /* we want synchronous operation */
            pSendPacket->Completion = NULL;
            HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
            status = HTCIssueSend(target,pSendPacket);

            if (A_FAILED(status)) {
                break;
            }

                /* wait for response */
            status = HTCWaitforControlMessage(target, &pRecvPacket);

            if (A_FAILED(status)) {
                break;
            }
                /* we controlled the buffer creation so it has to be properly aligned */
            pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)pRecvPacket->pBuffer;

            if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) ||
                (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) {
                    /* this message is not valid */
                AR_DEBUG_ASSERT(FALSE);
                status = A_EPROTO;
                break;
            }

            pConnectResp->ConnectRespCode = pResponseMsg->Status;
                /* check response status */
            if (pResponseMsg->Status != HTC_SERVICE_SUCCESS) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                    (" Target failed service 0x%X connect request (status:%d)\n",
                                pResponseMsg->ServiceID, pResponseMsg->Status));
                status = A_EPROTO;
                break;
            }

            assignedEndpoint = (HTC_ENDPOINT_ID) pResponseMsg->EndpointID;
            maxMsgSize = pResponseMsg->MaxMsgSize;

            if ((pConnectResp->pMetaData != NULL) &&
                (pResponseMsg->ServiceMetaLength > 0) &&
                (pResponseMsg->ServiceMetaLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
                    /* caller supplied a buffer and the target responded with data */
                int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength);
                    /* copy the meta data */
                A_MEMCPY(pConnectResp->pMetaData,
                         ((A_UINT8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG),
                         copyLength);
                pConnectResp->ActualLength = copyLength;
            }

        }

            /* the rest of these are parameter checks so set the error status */
        status = A_EPROTO;

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

        if (0 == maxMsgSize) {
            AR_DEBUG_ASSERT(FALSE);
            break;
        }

        pEndpoint = &target->EndPoint[assignedEndpoint];
        pEndpoint->Id = assignedEndpoint;
        if (pEndpoint->ServiceID != 0) {
            /* endpoint already in use! */
            AR_DEBUG_ASSERT(FALSE);
            break;
        }

            /* return assigned endpoint to caller */
        pConnectResp->Endpoint = assignedEndpoint;
        pConnectResp->MaxMsgLength = maxMsgSize;

            /* setup the endpoint */
        pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */
        pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth;
        pEndpoint->MaxMsgLength = maxMsgSize;
            /* copy all the callbacks */
        pEndpoint->EpCallBacks = pConnectReq->EpCallbacks;
            /* set the credit distribution info for this endpoint, this information is
             * passed back to the credit distribution callback function */
        pEndpoint->CreditDist.ServiceID = pConnectReq->ServiceID;
        pEndpoint->CreditDist.pHTCReserved = pEndpoint;
        pEndpoint->CreditDist.Endpoint = assignedEndpoint;
        pEndpoint->CreditDist.TxCreditSize = target->TargetCreditSize;
        
        if (pConnectReq->MaxSendMsgSize != 0) {
                /* override TxCreditsPerMaxMsg calculation, this optimizes the credit-low indications
                 * since the host will actually issue smaller messages in the Send path */
            if (pConnectReq->MaxSendMsgSize > maxMsgSize) {
                    /* can't be larger than the maximum the target can support */
                AR_DEBUG_ASSERT(FALSE);
                break;       
            }
            pEndpoint->CreditDist.TxCreditsPerMaxMsg = pConnectReq->MaxSendMsgSize / target->TargetCreditSize;
        } else {
            pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize;
        }
        
        if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
            pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1;
        }
        
            /* save local connection flags */
        pEndpoint->LocalConnectionFlags = pConnectReq->LocalConnectionFlags;
        
        status = A_OK;

    } while (FALSE);

    if (pSendPacket != NULL) {
        HTC_FREE_CONTROL_TX(target,pSendPacket);
    }

    if (pRecvPacket != NULL) {
        HTC_FREE_CONTROL_RX(target,pRecvPacket);
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n"));

    return status;
}
Beispiel #25
0
A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle)
{
    A_STATUS                status = A_OK;
    HTC_TARGET              *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_READY_EX_MSG        *pReadyMsg;
    HTC_SERVICE_CONNECT_REQ  connect;
    HTC_SERVICE_CONNECT_RESP resp;
    HTC_READY_MSG *rdy_msg;
    A_UINT16 htc_rdy_msg_id;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%p) \n", HTCHandle));
    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n"));

    do {

        status = HIFStart(target->hif_dev);
        if (A_FAILED(status)) {
            break;
        }

        status = HTCWaitRecvCtrlMessage(target);

        if (A_FAILED(status)) {
            break;
        }

        if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid HTC Ready Msg Len:%d! \n",target->CtrlResponseLength));
            status = A_ECOMM;
            break;
        }

        pReadyMsg = (HTC_READY_EX_MSG *)target->CtrlResponseBuffer;

        rdy_msg = &pReadyMsg->Version2_0_Info;
        htc_rdy_msg_id = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID);
        if (htc_rdy_msg_id != HTC_MSG_READY_ID) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                        ("Invalid HTC Ready Msg : 0x%X ! \n",htc_rdy_msg_id));
            status = A_ECOMM;
            break;
        }

        target->TotalTransmitCredits = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITCOUNT);
        target->TargetCreditSize = (int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE);

        AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("Target Ready! : transmit resources : %d size:%d\n",
                target->TotalTransmitCredits, target->TargetCreditSize));

        if ((0 == target->TotalTransmitCredits) || (0 == target->TargetCreditSize)) {
            status = A_ECOMM;
            break;
        }
            /* done processing */
        target->CtrlResponseProcessing = FALSE;

        HTCSetupTargetBufferAssignments(target);

            /* setup our pseudo HTC control endpoint connection */
        A_MEMZERO(&connect,sizeof(connect));
        A_MEMZERO(&resp,sizeof(resp));
        connect.EpCallbacks.pContext = target;
        connect.EpCallbacks.EpTxComplete = HTCControlTxComplete;
        connect.EpCallbacks.EpRecv = HTCControlRxComplete;
        connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS;
        connect.ServiceID = HTC_CTRL_RSVD_SVC;

            /* connect fake service */
        status = HTCConnectService((HTC_HANDLE)target,
                                   &connect,
                                   &resp);

    } while (FALSE);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit (%d)\n",status));
    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("-HWT\n"));
    return status;
}
Beispiel #26
0
/* get the low level HIF device for the caller , the caller may wish to do low level
 * HIF requests */
void *HTCGetHifDevice(HTC_HANDLE HTCHandle)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    return target->hif_dev;
}
Beispiel #27
0
/* Start HTC, enable interrupts and let the target know host has finished setup */
A_STATUS HTCStart(HTC_HANDLE HTCHandle)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_PACKET *pPacket;
    A_STATUS   status;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));
	printk("HTCStart Enter\n");

        /* make sure interrupts are disabled at the chip level,
         * this function can be called again from a reboot of the target without shutting down HTC */
    DevDisableInterrupts(&target->Device);
        /* make sure state is cleared again */
    target->HTCStateFlags = 0;
        
        /* now that we are starting, push control receive buffers into the
         * HTC control endpoint */

    while (1) {
        pPacket = HTC_ALLOC_CONTROL_RX(target);
        if (NULL == pPacket) {
            break;
        }
        HTCAddReceivePkt((HTC_HANDLE)target,pPacket);
    }

    do {

        AR_DEBUG_ASSERT(target->InitCredits != NULL);
        AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL);
        AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL);

            /* call init credits callback to do the distribution ,
             * NOTE: the first entry in the distribution list is ENDPOINT_0, so
             * we pass the start of the list after this one. */
        target->InitCredits(target->pCredDistContext,
                            target->EpCreditDistributionListHead->pNext,
                            target->TargetCredits);

        if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
            DumpCreditDistStates(target);
        }

            /* the caller is done connecting to services, so we can indicate to the
            * target that the setup phase is complete */
        status = HTCSendSetupComplete(target);
        if (A_FAILED(status)) {
            break;
        }

        /* unmask interrupts */
        status = DevUnmaskInterrupts(&target->Device);
        if (A_FAILED(status)) {
            HTCStop(target);
        }

    } while (FALSE);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
	printk("HTCStart Exit\n");
    return status;
}
Beispiel #28
0
/* wait for the target to arrive (sends HTC Ready message)
 * this operation is fully synchronous and the message is polled for */
A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle)
{
    HTC_TARGET              *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    A_STATUS                 status;
    HTC_PACKET              *pPacket = NULL;
    HTC_READY_MSG           *pRdyMsg;
    HTC_SERVICE_CONNECT_REQ  connect;
    HTC_SERVICE_CONNECT_RESP resp;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%X) \n", (A_UINT32)target));


    do {

#ifdef MBOXHW_UNIT_TEST

        status = DoMboxHWTest(&target->Device);

        if (status != A_OK) {
            break;
        }

#endif

		/* we should be getting 1 control message that the target is ready */
        status = HTCWaitforControlMessage(target, &pPacket);

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n"));
            break;
        }

		/* we controlled the buffer creation so it has to be properly aligned */
        pRdyMsg = (HTC_READY_MSG *)pPacket->pBuffer;

        if ((pRdyMsg->MessageID != HTC_MSG_READY_ID) ||
            (pPacket->ActualLength < sizeof(HTC_READY_MSG))) {
                /* this message is not valid */
            AR_DEBUG_ASSERT(FALSE);
            status = A_EPROTO;
            break;
        }

        if (pRdyMsg->CreditCount == 0 || pRdyMsg->CreditSize == 0) {
              /* this message is not valid */
            AR_DEBUG_ASSERT(FALSE);
            status = A_EPROTO;
            break;
        }

        target->TargetCredits = pRdyMsg->CreditCount;
        target->TargetCreditSize = pRdyMsg->CreditSize;

        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Target Ready: credits: %d credit size: %d\n",
                target->TargetCredits, target->TargetCreditSize));

		printk(" Target Ready: credits: %d credit size: %d\n",target->TargetCredits, target->TargetCreditSize);
			

            /* setup our pseudo HTC control endpoint connection */
        A_MEMZERO(&connect,sizeof(connect));
        A_MEMZERO(&resp,sizeof(resp));
        connect.EpCallbacks.pContext = target;
        connect.EpCallbacks.EpTxComplete = HTCControlTxComplete;
        connect.EpCallbacks.EpRecv = HTCControlRecv;
        connect.EpCallbacks.EpRecvRefill = NULL;  /* not needed */
        connect.EpCallbacks.EpSendFull = NULL;    /* not nedded */
        connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS;
        connect.ServiceID = HTC_CTRL_RSVD_SVC;

            /* connect fake service */
        status = HTCConnectService((HTC_HANDLE)target,
                                   &connect,
                                   &resp);

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

    } while (FALSE);

    if (pPacket != NULL) {
        HTC_FREE_CONTROL_RX(target,pPacket);
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n"));

    return status;
}
Beispiel #29
0
/* set the instance block for this HTC handle, so that on removal, the blob can be
 * returned to the caller */
void HTCSetInstance(HTC_HANDLE HTCHandle, void *Instance)
{
    HTC_TARGET  *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);

    target->pInstanceContext = Instance;
}
Beispiel #30
0
void *htc_get_targetdef(HTC_HANDLE htc_handle)
{
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);

	return hif_get_targetdef(target->hif_dev);
}