Example #1
0
static void DoRecvCompletion(HTC_ENDPOINT     *pEndpoint,
                             HTC_PACKET_QUEUE *pQueueToIndicate)
{

    do {

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

        if (pEndpoint->EpCallBacks.EpRecvPktMultiple != NULL) {
            AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d, recv multiple callback (%d pkts) \n",
                     pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
                /* a recv multiple handler is being used, pass the queue to the handler */
            pEndpoint->EpCallBacks.EpRecvPktMultiple(pEndpoint->EpCallBacks.pContext,
                                                     pQueueToIndicate);
            INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
        } else {
            HTC_PACKET *pPacket;
            /* using legacy EpRecv */
            while (!HTC_QUEUE_EMPTY(pQueueToIndicate)) {
                pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
                AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d recv callback on packet %p \n",
                        pEndpoint->Id, pPacket));
                pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket);
            }
        }

    } while (FALSE);

}
Example #2
0
File: htc.c Project: KHATEEBNSIT/AP
static void ResetEndpointStates(HTC_TARGET *target)
{
    HTC_ENDPOINT        *pEndpoint;
    int                  i;

    for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
        pEndpoint = &target->EndPoint[i];
        pEndpoint->ServiceID = 0;
        pEndpoint->MaxMsgLength = 0;
        pEndpoint->MaxTxQueueDepth = 0;
        pEndpoint->Id = i;
        INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
        INIT_HTC_PACKET_QUEUE(&pEndpoint->TxLookupQueue);
        INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBufferHoldQueue);
        pEndpoint->target = target;
        //pEndpoint->TxCreditFlowEnabled = (A_BOOL)htc_credit_flow;
        pEndpoint->TxCreditFlowEnabled = (A_BOOL)1;
        adf_os_atomic_init(&pEndpoint->TxProcessCount);
    }
}
Example #3
0
static void RefillRecvBuffers(struct ar6k_hci_bridge_info      *pHcidevInfo, 
                              HCI_TRANSPORT_PACKET_TYPE Type, 
                              int                       NumBuffers)
{
    int                 length, i;
    void                *osBuf = NULL;
    struct htc_packet_queue    queue;
    struct htc_packet          *pPacket;

    INIT_HTC_PACKET_QUEUE(&queue);
    
    if (Type == HCI_ACL_TYPE) {     
        if (pHcidevInfo->HciNormalMode) {  
            length = HCI_MAX_FRAME_SIZE;
        } else {
            length = MAX_ACL_RECV_LENGTH;    
        }
    } else {
        length = MAX_EVT_RECV_LENGTH;
    }
    
        /* add on transport head and tail room */ 
    length += pHcidevInfo->HCIProps.HeadRoom + pHcidevInfo->HCIProps.TailRoom;
        /* round up to the required I/O padding */      
    length = BLOCK_ROUND_UP_PWR2(length,pHcidevInfo->HCIProps.IOBlockPad);
             
    for (i = 0; i < NumBuffers; i++) {   
           
        if (pHcidevInfo->HciNormalMode) {   
            osBuf = bt_alloc_buffer(pHcidevInfo,length);       
        } else {
            osBuf = A_NETBUF_ALLOC(length);  
        }
          
        if (NULL == osBuf) {
            break;    
        }            
         
        pPacket = AllocHTCStruct(pHcidevInfo);
        if (NULL == pPacket) {
            FreeBtOsBuf(pHcidevInfo,osBuf);
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
            break;    
        }     
        
        SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length,Type);
            /* add to queue */
        HTC_PACKET_ENQUEUE(&queue,pPacket);
    }
    
    if (i > 0) {
        HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue);    
    }
}
Example #4
0
static void ResetEndpointStates(HTC_TARGET *target)
{
    HTC_ENDPOINT        *pEndpoint;
    int                  i;

    for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
        pEndpoint = &target->EndPoint[i];
        
        A_MEMZERO(&pEndpoint->CreditDist, sizeof(pEndpoint->CreditDist));
        pEndpoint->ServiceID = 0;
        pEndpoint->CurrentTxQueueDepth = 0;
        pEndpoint->MaxMsgLength = 0;
        pEndpoint->MaxTxQueueDepth = 0;
#ifdef HTC_EP_STAT_PROFILING
        A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats));
#endif
        INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers);
        INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
    }
        /* reset distribution list */
    target->EpCreditDistributionListHead = NULL;
}
Example #5
0
A_STATUS DevSetup(AR6K_DEVICE *pDev)
{
    A_UINT32 blocksizes[AR6K_MAILBOXES];
    A_STATUS status = A_OK;
    int      i;
    HTC_CALLBACKS htcCallbacks;

    do {

        DL_LIST_INIT(&pDev->ScatterReqHead);
           /* initialize our free list of IO packets */
        INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList);
        A_MUTEX_INIT(&pDev->Lock);

        A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
            /* the device layer handles these */
        htcCallbacks.rwCompletionHandler = DevRWCompletionHandler;
        htcCallbacks.dsrHandler = DevDsrHandler;
        htcCallbacks.context = pDev;

        status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks);

        if (A_FAILED(status)) {
            break;
        }

        pDev->HifAttached = TRUE;

            /* get the addresses for all 4 mailboxes */
        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
                                    &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo));

        if (status != A_OK) {
            A_ASSERT(FALSE);
            break;
        }

            /* carve up register I/O packets (these are for ASYNC register I/O ) */
        for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) {
            HTC_PACKET *pIOPacket;
            pIOPacket = &pDev->RegIOBuffers[i].HtcPacket;
            SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket,
                                          pDev,
                                          pDev->RegIOBuffers[i].Buffer,
                                          AR6K_REG_IO_BUFFER_SIZE,
                                          0); /* don't care */
            AR6KFreeIOPacket(pDev,pIOPacket);
        }

            /* get the block sizes */
        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
                                    blocksizes, sizeof(blocksizes));

        if (status != A_OK) {
            A_ASSERT(FALSE);
            break;
        }

            /* note: we actually get the block size of a mailbox other than 0, for SDIO the block
             * size on mailbox 0 is artificially set to 1.  So we use the block size that is set
             * for the other 3 mailboxes */
        pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE];
            /* must be a power of 2 */
        A_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0);

            /* assemble mask, used for padding to a block */
        pDev->BlockMask = pDev->BlockSize - 1;

        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n",
                    pDev->BlockSize, pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]));

        pDev->GetPendingEventsFunc = NULL;
            /* see if the HIF layer implements the get pending events function  */
        HIFConfigureDevice(pDev->HIFDevice,
                           HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
                           &pDev->GetPendingEventsFunc,
                           sizeof(pDev->GetPendingEventsFunc));

            /* assume we can process HIF interrupt events asynchronously */
        pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC;

            /* see if the HIF layer overrides this assumption */
        HIFConfigureDevice(pDev->HIFDevice,
                           HIF_DEVICE_GET_IRQ_PROC_MODE,
                           &pDev->HifIRQProcessingMode,
                           sizeof(pDev->HifIRQProcessingMode));

        switch (pDev->HifIRQProcessingMode) {
            case HIF_DEVICE_IRQ_SYNC_ONLY:
                AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYNC ONLY\n"));
                    /* see if HIF layer wants HTC to yield */
                HIFConfigureDevice(pDev->HIFDevice,
                                   HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
                                   &pDev->HifIRQYieldParams,
                                   sizeof(pDev->HifIRQYieldParams));

                if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) {
                    AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
                        ("HIF requests that DSR yield per %d RECV packets \n",
                        pDev->HifIRQYieldParams.RecvPacketYieldCount));
                    pDev->DSRCanYield = TRUE;
                }
                break;
            case HIF_DEVICE_IRQ_ASYNC_SYNC:
                AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n"));
                break;
            default:
                A_ASSERT(FALSE);
        }

        pDev->HifMaskUmaskRecvEvent = NULL;

            /* see if the HIF layer implements the mask/unmask recv events function  */
        HIFConfigureDevice(pDev->HIFDevice,
                           HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
                           &pDev->HifMaskUmaskRecvEvent,
                           sizeof(pDev->HifMaskUmaskRecvEvent));

        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n",
                 (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev->HifMaskUmaskRecvEvent));

        status = DevDisableInterrupts(pDev);

        if (A_FAILED(status)) {
            break;
        }

        status = DevSetupGMbox(pDev);

    } while (FALSE);

    if (A_FAILED(status)) {
        if (pDev->HifAttached) {
            HIFDetachHTC(pDev->HIFDevice);
            pDev->HifAttached = FALSE;
        }
    }

    return status;

}
Example #6
0
File: htc.c Project: KHATEEBNSIT/AP
/* registered target arrival callback from the HIF layer */
HTC_HANDLE HTCCreate(void *hHIF, HTC_INIT_INFO *pInfo, adf_os_device_t osdev)
{
    MSG_BASED_HIF_CALLBACKS htcCallbacks;
    HTC_ENDPOINT            *pEndpoint=NULL;
    HTC_TARGET              *target = NULL;
    int                     i;

    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("+HTCCreate ..  HIF :%p \n",hHIF));

    A_REGISTER_MODULE_DEBUG_INFO(htc);

    if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTC : Unable to allocate memory\n"));
        return NULL;
    }

    A_MEMZERO(target, sizeof(HTC_TARGET));

    adf_os_spinlock_init(&target->HTCLock);
    adf_os_spinlock_init(&target->HTCRxLock);
    adf_os_spinlock_init(&target->HTCTxLock);

    do {
        A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO));
        target->host_handle = pInfo->pContext;
		target->osdev = osdev;

        ResetEndpointStates(target);

        INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);

        for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) {
            HTC_PACKET *pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET));
            if (pPacket != NULL) {
                A_MEMZERO(pPacket,sizeof(HTC_PACKET));
                FreeHTCPacketContainer(target,pPacket);
            }
        }

#ifdef TODO_FIXME
        for (i = 0; i < NUM_CONTROL_TX_BUFFERS; i++) {
            pPacket = BuildHTCTxCtrlPacket();
            if (NULL == pPacket) {
                break;
            }
            HTCFreeControlTxPacket(target,pPacket);
        }
#endif

        /* setup HIF layer callbacks */
        A_MEMZERO(&htcCallbacks, sizeof(MSG_BASED_HIF_CALLBACKS));
        htcCallbacks.Context = target;
        htcCallbacks.rxCompletionHandler = HTCRxCompletionHandler;
        htcCallbacks.txCompletionHandler = HTCTxCompletionHandler;
        htcCallbacks.txResourceAvailHandler = HTCTxResourceAvailHandler;
        htcCallbacks.fwEventHandler = HTCFwEventHandler;
        target->hif_dev = hHIF;

        /* Get HIF default pipe for HTC message exchange */
        pEndpoint = &target->EndPoint[ENDPOINT_0];

        HIFPostInit(hHIF, target, &htcCallbacks);
        HIFGetDefaultPipe(hHIF, &pEndpoint->UL_PipeID, &pEndpoint->DL_PipeID);

    } while (FALSE);

    HTCRecvInit(target);

    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("-HTCCreate (0x%p) \n", target));

    return (HTC_HANDLE)target;
}
Example #7
0
/* registered target arrival callback from the HIF layer */
HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo)
{
    HTC_TARGET              *target = NULL;
    A_STATUS                 status = A_OK;
    int                      i;
    A_UINT32                 ctrl_bufsz;
    A_UINT32                 blocksizes[HTC_MAILBOX_NUM_MAX];

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n"));
	printk("HTCCreate !!\n");

    do {

            /* allocate target memory */
        if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) 
		{
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
            status = A_ERROR;
            break;
        }

        A_MEMZERO(target, sizeof(HTC_TARGET));
        A_MUTEX_INIT(&target->HTCLock);
        A_MUTEX_INIT(&target->HTCRxLock);
        A_MUTEX_INIT(&target->HTCTxLock);
        INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
        INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList);

            /* give device layer the hif device handle */
        target->Device.HIFDevice = hif_handle;
            /* give the device layer our context (for event processing)
             * the device layer will register it's own context with HIF
             * so we need to set this so we can fetch it in the target remove handler */
        target->Device.HTCContext = target;
            /* set device layer target failure callback */
        target->Device.TargetFailureCallback = HTCReportFailure;
            /* set device layer recv message pending callback */
        target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler;
        target->EpWaitingForBuffers = ENDPOINT_MAX;

        A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO));
          
            /* setup device layer */
        status = DevSetup(&target->Device);

        if (A_FAILED(status)) {
            break;
        }


        /* get the block sizes */
        status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
                                    blocksizes, sizeof(blocksizes));
        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from HIF layer...\n"));
            break;
        }

        /* Set the control buffer size based on the block size */
        if (blocksizes[1] > HTC_MAX_CONTROL_MESSAGE_LENGTH) 
		{
            ctrl_bufsz = blocksizes[1] + HTC_HDR_LENGTH;
        } 
		else 
		{
            ctrl_bufsz = HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH;
        }

		
        for (i = 0;i < NUM_CONTROL_BUFFERS;i++) 
		{
            target->HTCControlBuffers[i].Buffer = A_MALLOC(ctrl_bufsz);	
            if (target->HTCControlBuffers[i].Buffer == NULL) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
                status = A_ERROR;
                break;
            }
        }

        if (A_FAILED(status)) {
            break;
        }

            /* carve up buffers/packets for control messages */
        for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) {
            HTC_PACKET *pControlPacket;
            pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
            SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket,
                                          target,
                                          target->HTCControlBuffers[i].Buffer,
                                          ctrl_bufsz,
                                          ENDPOINT_0);
            HTC_FREE_CONTROL_RX(target,pControlPacket);
        }

        for (;i < NUM_CONTROL_BUFFERS;i++) {
             HTC_PACKET *pControlPacket;
             pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
             INIT_HTC_PACKET_INFO(pControlPacket,
                                  target->HTCControlBuffers[i].Buffer,
                                  ctrl_bufsz);
             HTC_FREE_CONTROL_TX(target,pControlPacket);
        }

    } while (FALSE);

    if (A_FAILED(status)) {
        if (target != NULL) {
            HTCCleanup(target);
            target = NULL;
        }
    }

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

    return target;
}
A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar)
#endif
{
    HCI_TRANSPORT_CONFIG_INFO config;
    A_STATUS                  status = A_OK;
    int                       i;
    HTC_PACKET                *pPacket;
    AR6K_HCI_BRIDGE_INFO      *pHcidevInfo;
        
       
    do {
        
        pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)A_MALLOC(sizeof(AR6K_HCI_BRIDGE_INFO));
        
        if (NULL == pHcidevInfo) {
            status = A_NO_MEMORY;
            break;    
        }
        
        A_MEMZERO(pHcidevInfo, sizeof(AR6K_HCI_BRIDGE_INFO));
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
        g_pHcidevInfo = pHcidevInfo;
        pHcidevInfo->HCITransHdl = *(HCI_TRANSPORT_MISC_HANDLES *)ar;
#else
        ar->hcidev_info = pHcidevInfo;
        pHcidevInfo->ar = ar;
#endif
        spin_lock_init(&pHcidevInfo->BridgeLock);
        INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead);

        ar->exitCallback = AR3KConfigureExit;
    
        status = bt_setup_hci(pHcidevInfo);
        if (A_FAILED(status)) {
            break;    
        }
        
        if (pHcidevInfo->HciNormalMode) {      
            AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n"));    
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n"));     
        }
        
        pHcidevInfo->pHTCStructAlloc = (A_UINT8 *)A_MALLOC((sizeof(HTC_PACKET)) * NUM_HTC_PACKET_STRUCTS);
        
        if (NULL == pHcidevInfo->pHTCStructAlloc) {
            status = A_NO_MEMORY;
            break;    
        }
        
        pPacket = (HTC_PACKET *)pHcidevInfo->pHTCStructAlloc;
        for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) {
            FreeHTCStruct(pHcidevInfo,pPacket);                
        }
        
        A_MEMZERO(&config,sizeof(HCI_TRANSPORT_CONFIG_INFO));        
        config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2;
        config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2;
        config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH;
        config.pContext = pHcidevInfo;    
        config.TransportFailure = ar6000_hci_transport_failure;
        config.TransportReady = ar6000_hci_transport_ready;
        config.TransportRemoved = ar6000_hci_transport_removed;
        config.pHCISendComplete = ar6000_hci_send_complete;
        config.pHCIPktRecv = ar6000_hci_pkt_recv;
        config.pHCIPktRecvRefill = ar6000_hci_pkt_refill;
        config.pHCISendFull = ar6000_hci_pkt_send_full;
       
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
        pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config);
#else
        pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config);
#endif

        if (NULL == pHcidevInfo->pHCIDev) {
            status = A_ERROR;      
        }
    
    } while (FALSE);
    
    if (A_FAILED(status)) {
        if (pHcidevInfo != NULL) {
            if (NULL == pHcidevInfo->pHCIDev) {
                /* GMBOX may not be present in older chips */
                /* just return success */ 
                status = A_OK;
            }
        }
        ar6000_cleanup_hci(ar);    
    }
    
    return status;
}
Example #9
0
/* registered target arrival callback from the HIF layer */
HTC_HANDLE htc_create(void *ol_sc, HTC_INIT_INFO *pInfo, cdf_device_t osdev)
{
	struct hif_msg_callbacks htcCallbacks;
	HTC_ENDPOINT *pEndpoint = NULL;
	HTC_TARGET *target = NULL;
	int i;

	if (ol_sc == NULL) {
		HTC_ERROR("%s: ol_sc = NULL", __func__);
		return NULL;
	}
	HTC_TRACE("+htc_create ..  HIF :%p", ol_sc);

	A_REGISTER_MODULE_DEBUG_INFO(htc);

	target = (HTC_TARGET *) cdf_mem_malloc(sizeof(HTC_TARGET));
	if (target == NULL) {
		HTC_ERROR("%s: Unable to allocate memory", __func__);
		return NULL;
	}

	A_MEMZERO(target, sizeof(HTC_TARGET));

	cdf_spinlock_init(&target->HTCLock);
	cdf_spinlock_init(&target->HTCRxLock);
	cdf_spinlock_init(&target->HTCTxLock);
	cdf_spinlock_init(&target->HTCCreditLock);

	do {
		A_MEMCPY(&target->HTCInitInfo, pInfo, sizeof(HTC_INIT_INFO));
		target->host_handle = pInfo->pContext;
		target->osdev = osdev;

		reset_endpoint_states(target);

		INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);

		for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) {
			HTC_PACKET *pPacket =
				(HTC_PACKET *) cdf_mem_malloc(sizeof(HTC_PACKET));
			if (pPacket != NULL) {
				A_MEMZERO(pPacket, sizeof(HTC_PACKET));
				free_htc_packet_container(target, pPacket);
			}
		}

#ifdef TODO_FIXME
		for (i = 0; i < NUM_CONTROL_TX_BUFFERS; i++) {
			pPacket = build_htc_tx_ctrl_packet();
			if (NULL == pPacket) {
				break;
			}
			htc_free_control_tx_packet(target, pPacket);
		}
#endif

		/* setup HIF layer callbacks */
		cdf_mem_zero(&htcCallbacks, sizeof(struct hif_msg_callbacks));
		htcCallbacks.Context = target;
		htcCallbacks.rxCompletionHandler = htc_rx_completion_handler;
		htcCallbacks.txCompletionHandler = htc_tx_completion_handler;
		htcCallbacks.txResourceAvailHandler = htc_tx_resource_avail_handler;
		htcCallbacks.fwEventHandler = htc_fw_event_handler;
		target->hif_dev = ol_sc;

		/* Get HIF default pipe for HTC message exchange */
		pEndpoint = &target->EndPoint[ENDPOINT_0];

		hif_post_init(target->hif_dev, target, &htcCallbacks);
		hif_get_default_pipe(target->hif_dev, &pEndpoint->UL_PipeID,
				     &pEndpoint->DL_PipeID);

	} while (false);

	htc_recv_init(target);

	HTC_TRACE("-htc_create: (0x%p)", target);

	return (HTC_HANDLE) target;
}
Example #10
0
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;
    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;

            status = HTCIssueSend(target,pSendPacket,0);

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

        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;
        INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers);
        INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
        /* 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;
        pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize;

        if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
            pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1;
        }

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