コード例 #1
0
ファイル: TxnQueue.c プロジェクト: aleho/ti_wilink
/** 
 * \fn     txnQ_RunScheduler
 * \brief  Send queued transactions
 * 
 * Run the scheduler, which issues transactions as long as possible.
 * Since this function is called from either internal or external (TxnDone) context,
 *   it handles reentry by setting a bSchedulerPend flag, and running the scheduler again
 *   when its current iteration is finished.
 * 
 * \note   
 * \param  pTxnQ     - The module's object
 * \param  pInputTxn - The transaction inserted in the current context (NULL if none)
 * \return COMPLETE if pCurrTxn completed in this context, PENDING if not, ERROR if failed
 * \sa     
 */ 
static ETxnStatus txnQ_RunScheduler (TTxnQObj *pTxnQ, TTxnStruct *pInputTxn)
{
    TI_BOOL bFirstIteration;  
	ETxnStatus eStatus = TXN_STATUS_NONE;

    TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_RunScheduler()\n");

    context_EnterCriticalSection (pTxnQ->hContext);

    /* If the scheduler is currently busy, set bSchedulerPend flag and exit */
    if (pTxnQ->bSchedulerBusy)
    {
        TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_RunScheduler(): Scheduler is busy\n");
        pTxnQ->bSchedulerPend = TI_TRUE;
        context_LeaveCriticalSection (pTxnQ->hContext);
        return TXN_STATUS_PENDING;
    }

    /* Indicate that the scheduler is currently busy */
    pTxnQ->bSchedulerBusy = TI_TRUE;

    context_LeaveCriticalSection (pTxnQ->hContext);

    bFirstIteration = TI_TRUE;  

    /* 
     * Run the scheduler while it has work to do 
     */
    while (1)
    {
        /* If first scheduler iteration, save its return code to return the original Txn result */
        if (bFirstIteration) 
        {
            eStatus = txnQ_Scheduler (pTxnQ, pInputTxn);
            bFirstIteration = TI_FALSE;
        }
        /* This is for handling pending calls when the scheduler was busy (see above) */
        else 
        {    
            TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_RunScheduler(): Handle pending scheduler call\n");
            txnQ_Scheduler (pTxnQ, NULL);
        }

        context_EnterCriticalSection (pTxnQ->hContext);

        /* If no pending calls, clear the busy flag and return the original caller Txn status */
        if (!pTxnQ->bSchedulerPend) 
        {
            pTxnQ->bSchedulerBusy = TI_FALSE;
            context_LeaveCriticalSection (pTxnQ->hContext);
            return eStatus;
        }
        pTxnQ->bSchedulerPend = TI_FALSE;

        context_LeaveCriticalSection (pTxnQ->hContext);
    }
}
コード例 #2
0
/** 
 * \fn     twIf_TxnDoneCb
 * \brief  Transaction completion CB
 * 
 * This callback is called by the TxnQ upon transaction completion, unless is was completed in
 *     the original context where it was issued.
 * It may be called from bus driver external context (TxnDone ISR) or from WLAN driver context.
 *  
 * \note   
 * \param  hTwIf - The module's object
 * \param  pTxn  - The completed transaction object 
 * \return void
 * \sa     twIf_HandleTxnDone
 */
static void twIf_TxnDoneCb(TI_HANDLE hTwIf, TTxnStruct * pTxn)
{
	TTwIfObj *pTwIf = (TTwIfObj *) hTwIf;

#ifdef TI_DBG
	pTwIf->uDbgCountTxnDoneCb++;
	TRACE6(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
	       "twIf_TxnDoneCb: Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n",
	       pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0], pTxn->aLen[1],
	       pTxn->aLen[2], pTxn->aLen[3]);
#endif

	/* In case of recovery flag, Call directly restart callback */
	if (TXN_PARAM_GET_STATUS(pTxn) == TXN_PARAM_STATUS_RECOVERY) {
		if (pTwIf->fRecoveryCb) {
			TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION,
			       "twIf_TxnDoneCb: During Recovery\n");
			pTwIf->bTxnDoneInRecovery = TI_TRUE;
			/* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
			context_RequestSchedule(pTwIf->hContext,
						pTwIf->uContextId);
			return;
		}
	}

	/* If the completed Txn is ELP, nothing to do (not counted) so exit */
	if (TXN_PARAM_GET_SINGLE_STEP(pTxn)) {
		return;
	}

	if (pTxn->fTxnDoneCb) {
		TI_STATUS eStatus;

		/* In critical section, enqueue the completed transaction in the TxnDoneQ. */
		context_EnterCriticalSection(pTwIf->hContext);
		eStatus = que_Enqueue(pTwIf->hTxnDoneQueue, (TI_HANDLE) pTxn);
		if (eStatus != TI_OK) {
			TRACE3(pTwIf->hReport, REPORT_SEVERITY_ERROR,
			       "twIf_TxnDoneCb(): Enqueue failed, pTxn=0x%x, HwAddr=0x%x, Len0=%d\n",
			       pTxn, pTxn->uHwAddr, pTxn->aLen[0]);
		}
		context_LeaveCriticalSection(pTwIf->hContext);
	} else {
		context_EnterCriticalSection(pTwIf->hContext);
		/* Decrement pending Txn counter, It's value will be checked in twIf_HandleTxnDone() */
		if (pTwIf->uPendingTxnCount > 0) {	/* in case of callback on recovery after restart */
			pTwIf->uPendingTxnCount--;
		}
		context_LeaveCriticalSection(pTwIf->hContext);

	}

	/* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
	context_RequestSchedule(pTwIf->hContext, pTwIf->uContextId);
}
コード例 #3
0
ファイル: TwIf.c プロジェクト: bluewater-cn/ti_wilink
/** 
 * \fn     twIf_TxnDoneCb
 * \brief  Transaction completion CB
 * 
 * This callback is called by the TxnQ upon transaction completion, unless is was completed in
 *     the original context where it was issued.
 * It may be called from bus driver external context (TxnDone ISR) or from WLAN driver context.
 *  
 * \note   
 * \param  hTwIf - The module's object
 * \param  pTxn  - The completed transaction object 
 * \return void
 * \sa     twIf_HandleTxnDone
 */ 
static void twIf_TxnDoneCb (TI_HANDLE hTwIf, TTxnStruct *pTxn)
{
    TTwIfObj *pTwIf = (TTwIfObj*)hTwIf;

#ifdef TI_DBG
    pTwIf->uDbgCountTxnDoneCb++;
#endif

    /* In case of recovery flag, Call directly restart callback */
    if (TXN_PARAM_GET_STATUS(pTxn) == TXN_PARAM_STATUS_RECOVERY)
    {
        if (pTwIf->fRecoveryCb)
        {
            pTwIf->bTxnDoneInRecovery = TI_TRUE;
            /* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
            context_RequestSchedule (pTwIf->hContext, pTwIf->uContextId);
            return;
        }
    }

    /* If the completed Txn is ELP, nothing to do (not counted) so exit */
    if (TXN_PARAM_GET_SINGLE_STEP(pTxn)) 
    {
        return;
    }

    if (pTxn->fTxnDoneCb)
    {
        TI_STATUS eStatus;

        /* In critical section, enqueue the completed transaction in the TxnDoneQ. */
        context_EnterCriticalSection (pTwIf->hContext);
        eStatus = que_Enqueue (pTwIf->hTxnDoneQueue, (TI_HANDLE)pTxn);
        context_LeaveCriticalSection (pTwIf->hContext);
    }
    else
    {
        context_EnterCriticalSection (pTwIf->hContext);
         /* Decrement pending Txn counter, It's value will be checked in twIf_HandleTxnDone() */
        if (pTwIf->uPendingTxnCount > 0) /* in case of callback on recovery after restart */
        {
            pTwIf->uPendingTxnCount--;
        }
        context_LeaveCriticalSection (pTwIf->hContext);

    }
    
    /* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
    context_RequestSchedule (pTwIf->hContext, pTwIf->uContextId);
}
コード例 #4
0
ファイル: TxnQueue.c プロジェクト: aleho/ti_wilink
ETxnStatus txnQ_Transact (TI_HANDLE hTxnQ, TTxnStruct *pTxn)
{
    TTxnQObj    *pTxnQ   = (TTxnQObj*)hTxnQ;
    TI_UINT32    uFuncId = TXN_PARAM_GET_FUNC_ID(pTxn);
    ETxnStatus   rc;

    if (TXN_PARAM_GET_SINGLE_STEP(pTxn)) 
    {
        pTxnQ->aFuncInfo[uFuncId].pSingleStep = pTxn;
        TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Transact(): Single step Txn\n");
    }
    else 
    {
        TI_STATUS eStatus;
        TI_HANDLE hQueue = pTxnQ->aTxnQueues[uFuncId][TXN_PARAM_GET_PRIORITY(pTxn)];
        context_EnterCriticalSection (pTxnQ->hContext);
        eStatus = que_Enqueue (hQueue, (TI_HANDLE)pTxn);
        context_LeaveCriticalSection (pTxnQ->hContext);
        if (eStatus != TI_OK)
        {
            TRACE3(pTxnQ->hReport, REPORT_SEVERITY_ERROR, "txnQ_Transact(): Enqueue failed, pTxn=0x%x, HwAddr=0x%x, Len0=%d\n", pTxn, pTxn->uHwAddr, pTxn->aLen[0]);
            return TXN_STATUS_ERROR;
        }
        TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Transact(): Regular Txn\n");
    }

    /* Send queued transactions as possible */
    rc = txnQ_RunScheduler (pTxnQ, pTxn); 

    return rc;
}
コード例 #5
0
ファイル: TxnQueue.c プロジェクト: aleho/ti_wilink
ETxnStatus txnQ_Restart (TI_HANDLE hTxnQ, TI_UINT32 uFuncId)
{
    TTxnQObj *pTxnQ = (TTxnQObj*) hTxnQ;

    TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Restart()\n");

    context_EnterCriticalSection (pTxnQ->hContext);

    /* If a Txn from the calling function is in progress, set state to RESTART return PENDING */
    if (pTxnQ->pCurrTxn) 
    {
        if (TXN_PARAM_GET_FUNC_ID(pTxnQ->pCurrTxn) == uFuncId)
        {
            pTxnQ->aFuncInfo[uFuncId].eState = FUNC_STATE_RESTART;

            context_LeaveCriticalSection (pTxnQ->hContext);

            TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_Restart(): pCurrTxn pending\n");

            /* Return PENDING to indicate that the restart will be completed later (in TxnDone) */
            return TXN_STATUS_PENDING;
        }
    }

    context_LeaveCriticalSection (pTxnQ->hContext);

    /* Clear the calling function's queues (call function CB with status=RECOVERY) */
    txnQ_ClearQueues (hTxnQ, uFuncId);

    /* Return COMPLETE to indicate that the restart was completed */
    return TXN_STATUS_COMPLETE;
}
コード例 #6
0
ファイル: timer.c プロジェクト: IdeosDev/vendor_ti_wlan
/**
 * \fn     tmr_GetExpiry
 * \brief  Called by OS-API upon any timer expiry
 *
 * This is the common callback function called upon expiartion of any timer.
 * It is called by the OS-API in timer expiry context and handles the transition
 *   to the driver's context for handling the expiry event.
 *
 * \note
 * \param  hTimerInfo - The specific timer handle
 * \return void
 * \sa     tmr_HandleExpiry
 */
void tmr_GetExpiry (TI_HANDLE hTimerInfo)
{
	TTimerInfo   *pTimerInfo   = (TTimerInfo *)hTimerInfo;                 /* The timer handle */
	TTimerModule *pTimerModule = (TTimerModule *)pTimerInfo->hTimerModule; /* The timer module handle */
	if (!pTimerModule) {
		WLAN_OS_REPORT (("tmr_GetExpiry(): ERROR - NULL timer!\n"));
		return;
	}

	/* Enter critical section */
	context_EnterCriticalSection (pTimerModule->hContext);

	/*
	 * If the expired timer was started when the driver's state was Operational,
	 *   insert it to the Operational-queue
	 */
	if (pTimerInfo->bOperStateWhenStarted) {
		que_Enqueue (pTimerModule->hOperQueue, hTimerInfo);
	}

	/*
	 * Else (started when driver's state was NOT-Operational), if now the state is still
	 *   NOT Operational insert it to the Init-queue.
	 *   (If state changed from non-operational to operational the event is ignored)
	 */
	else if (!pTimerModule->bOperState) {
		que_Enqueue (pTimerModule->hInitQueue, hTimerInfo);
	}

	/* Leave critical section */
	context_LeaveCriticalSection (pTimerModule->hContext);

	/* Request switch to driver context for handling timer events */
	context_RequestSchedule (pTimerModule->hContext, pTimerModule->uContextId);
}
コード例 #7
0
ファイル: timer.c プロジェクト: bluewater-cn/ti_wilink
/**
 * \fn     tmr_UpdateDriverState
 * \brief  Update driver state
 *
 * Under critical section, update driver state (operational or not),
 *   and if opertional, clear init queue.
 * Leave critical section and if operational state, request schedule for handling
 *   timer events in driver context (if any).
 *
 * \note
 * \param  hTimerModule - The timer module object
 * \param  bOperState   - TRUE if driver state is now operational, FALSE if not.
 * \return void
 * \sa
 */
void tmr_UpdateDriverState (TI_HANDLE hTimerModule, TI_BOOL bOperState)
{
    TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;

    if (bOperState == pTimerModule->bOperState)
    {
        return;
    }

    /* Enter critical section */
    context_EnterCriticalSection (pTimerModule->hContext);

    /* Save new state (TRUE means operational). */
    pTimerModule->bOperState = bOperState;

    /* If new state is operational */
    if (bOperState)
    {
        /* Increment the TWD initializations counter (for detecting recovery events). */
        pTimerModule->uTwdInitCount++;

        /* Empty the init queue (obsolete). */
        while (que_Dequeue (pTimerModule->hInitQueue) != NULL) {}
    }

    /* Leave critical section */
    context_LeaveCriticalSection (pTimerModule->hContext);

    /* If new state is operational, request switch to driver context for handling timer events */
    if (bOperState)
    {
        context_RequestSchedule (pTimerModule->hContext, pTimerModule->uContextId);
    }
}
コード例 #8
0
ファイル: timer.c プロジェクト: IdeosDev/vendor_ti_wlan
/**
 * \fn     tmr_Destroy
 * \brief  Destroy the module.
 *
 * Free the module's queues and object.
 *
 * \note   This is NOT a specific timer destruction! (see tmr_DestroyTimer)
 * \param  hTimerModule - The module object
 * \return TI_OK on success or TI_NOK on failure
 * \sa     tmr_Create
 */
TI_STATUS tmr_Destroy (TI_HANDLE hTimerModule)
{
	TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;

	if (!pTimerModule) {
		WLAN_OS_REPORT (("tmr_Destroy(): ERROR - NULL timer!\n"));
		return TI_NOK;
	}

	/* Alert if there are still timers that were not destroyed */
	if (pTimerModule->uTimersCount) {
		WLAN_OS_REPORT (("tmr_Destroy():  ERROR - Destroying Timer module but not all timers were destroyed!!\n"));
	}

	/* Destroy the module's queues (protect in critical section)) */
	context_EnterCriticalSection (pTimerModule->hContext);
	que_Destroy (pTimerModule->hInitQueue);
	que_Destroy (pTimerModule->hOperQueue);
	context_LeaveCriticalSection (pTimerModule->hContext);

	/* free module object */
	os_memoryFree (pTimerModule->hOs, pTimerModule, sizeof(TTimerModule));

	return TI_OK;
}
コード例 #9
0
ファイル: TxnQueue.c プロジェクト: IdeosDev/vendor_ti_wlan
/**
 * \fn     txnQ_ClearQueues
 * \brief  Clear the function queues
 *
 * Clear the specified function queues and call its CB for each Txn with status=RECOVERY.
 *
 * \note   Called in critical section.
 * \param  hTxnQ            - The module's object
 * \param  uFuncId          - The calling functional driver
 * \return void
 * \sa
 */
void txnQ_ClearQueues (TI_HANDLE hTxnQ, TI_UINT32 uFuncId)
{
	TTxnQObj        *pTxnQ = (TTxnQObj*)hTxnQ;
	TTxnStruct      *pTxn;
	TI_UINT32        uPrio;

	context_EnterCriticalSection (pTxnQ->hContext);

	pTxnQ->aFuncInfo[uFuncId].pSingleStep = NULL;

	/* For all function priorities */
	for (uPrio = 0; uPrio < pTxnQ->aFuncInfo[uFuncId].uNumPrios; uPrio++) {
		do {
			/* Dequeue Txn from current priority queue */
			pTxn = (TTxnStruct *) que_Dequeue (pTxnQ->aTxnQueues[uFuncId][uPrio]);

			/*
			 * Drop on Restart
			 * do not call fTxnQueueDoneCb (hCbHandle, pTxn) callback
			 */
		} while (pTxn != NULL);
	}

	/* Clear state - for restart (doesn't call txnQ_Open) */
	pTxnQ->aFuncInfo[uFuncId].eState = FUNC_STATE_RUNNING;

	context_LeaveCriticalSection (pTxnQ->hContext);
}
コード例 #10
0
/** 
 * \fn     twIf_ClearTxnDoneQueue
 * \brief  Clean the DoneQueue
 * 
 * Clear the specified done queue - don't call the callbacks.
 *  
 * \note   
 * \param  hTwIf - The module's object
 * \return void
 * \sa     
 */
static void twIf_ClearTxnDoneQueue(TI_HANDLE hTwIf)
{
	TTwIfObj *pTwIf = (TTwIfObj *) hTwIf;
	TTxnStruct *pTxn;

	/* Loop while there are completed transactions to handle */
	while (1) {
		/* In critical section, dequeue completed transaction from the TxnDoneQ. */
		context_EnterCriticalSection(pTwIf->hContext);
		pTxn = (TTxnStruct *) que_Dequeue(pTwIf->hTxnDoneQueue);
		context_LeaveCriticalSection(pTwIf->hContext);

		/* If no more transactions to handle, exit */
		if (pTxn != NULL) {
			/* Decrement pending Txn counter */
			if (pTwIf->uPendingTxnCount > 0) {	/* in case of callback on recovery after restart */
				pTwIf->uPendingTxnCount--;
			}

			/* 
			 * Drop on Recovery 
			 * do not call pTxn->fTxnDoneCb (pTxn->hCbHandle, pTxn) callback 
			 */
		}

		if (pTxn == NULL) {
			return;
		}
	}
}
コード例 #11
0
ファイル: TxnQueue.c プロジェクト: IdeosDev/vendor_ti_wlan
void txnQ_Close (TI_HANDLE  hTxnQ, TI_UINT32 uFuncId)
{
	TTxnQObj     *pTxnQ = (TTxnQObj*)hTxnQ;
	TI_UINT32     i;

	context_EnterCriticalSection (pTxnQ->hContext);

	/* Destroy the functional driver's queues */
	for (i = 0; i < pTxnQ->aFuncInfo[uFuncId].uNumPrios; i++) {
		que_Destroy (pTxnQ->aTxnQueues[uFuncId][i]);
	}

	/* Clear functional driver info */
	pTxnQ->aFuncInfo[uFuncId].uNumPrios       = 0;
	pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb = NULL;
	pTxnQ->aFuncInfo[uFuncId].hCbHandle       = NULL;
	pTxnQ->aFuncInfo[uFuncId].eState          = FUNC_STATE_NONE;

	/* Update functions actual range (to optimize Txn selection loops - see txnQ_SelectTxn) */
	pTxnQ->uMinFuncId      = MAX_FUNCTIONS;
	pTxnQ->uMaxFuncId      = 0;
	for (i = 0; i < MAX_FUNCTIONS; i++) {
		if (pTxnQ->aFuncInfo[i].eState != FUNC_STATE_NONE) {
			if (i < pTxnQ->uMinFuncId) {
				pTxnQ->uMinFuncId = i;
			}
			if (i > pTxnQ->uMaxFuncId) {
				pTxnQ->uMaxFuncId = i;
			}
		}
	}

	context_LeaveCriticalSection (pTxnQ->hContext);

}
コード例 #12
0
/** 
 * \fn     TxMgmtQ_FlushLinkQueues
 * \brief  Flush management queues the specific link
 * 
 * * \note   
 * \param  hTxMgmtQ   - The module's object                                          
 * \param  uHlid - link id                                          
 * \return void 
 * \sa     
 */ 
void TxMgmtQ_FlushLinkQueues(TI_HANDLE hTxMgmtQ, TI_UINT32 uHlid)
{
    TTxMgmtQ   *pTxMgmtQ = (TTxMgmtQ *)hTxMgmtQ;
    TTxCtrlBlk *pPktCtrlBlk;
    TI_UINT32  uQueId;
    TMgmtLinkQ *pLinkQ;

    pLinkQ = &pTxMgmtQ->aMgmtLinkQ[uHlid]; /* Link queues */

            /* Dequeue and free all queued packets */
    for (uQueId = 0 ; uQueId < NUM_OF_MGMT_QUEUES ; uQueId++)
    {
        while (1)
        {
            context_EnterCriticalSection (pTxMgmtQ->hContext);
            pPktCtrlBlk = (TTxCtrlBlk *) que_Dequeue (pLinkQ->aQueues[uQueId]);
            context_LeaveCriticalSection (pTxMgmtQ->hContext);
            if (pPktCtrlBlk == NULL) 
            {
                break;
            }
            txCtrl_FreePacket (pTxMgmtQ->hTxCtrl, pPktCtrlBlk, TI_NOK);
        }
    }
}
コード例 #13
0
ファイル: TxnQueue.c プロジェクト: IdeosDev/vendor_ti_wlan
/**
 * \fn     txnQ_TxnDoneCb
 * \brief  Pending Transaction completion CB
 *
 * Called back by bus-driver upon pending transaction completion in TxnDone context (external!).
 * Enqueue completed transaction in TxnDone queue and call scheduler to send queued transactions.
 *
 * \note
 * \param  hTxnQ - The module's object
 * \param  pTxn  - The completed transaction object
 * \return void
 * \sa
 */
static void txnQ_TxnDoneCb (TI_HANDLE hTxnQ, void *hTxn)
{
	TTxnQObj   *pTxnQ   = (TTxnQObj*)hTxnQ;
	TTxnStruct *pTxn    = (TTxnStruct *)hTxn;
	TI_UINT32   uFuncId = TXN_PARAM_GET_FUNC_ID(pTxn);

	/* If the function of the completed Txn is waiting for restart */
	if (pTxnQ->aFuncInfo[uFuncId].eState == FUNC_STATE_RESTART) {

		/* First, Clear the restarted function queues  */
		txnQ_ClearQueues (hTxnQ, uFuncId);

		/* Call function CB for current Txn with restart indication */
		TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_RECOVERY);
		pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb (pTxnQ->aFuncInfo[uFuncId].hCbHandle, pTxn);
	}

	/* In the normal case (no restart), enqueue completed transaction in TxnDone queue */
	else {
		TI_STATUS eStatus;

		context_EnterCriticalSection (pTxnQ->hContext);
		eStatus = que_Enqueue (pTxnQ->hTxnDoneQueue, (TI_HANDLE)pTxn);
		context_LeaveCriticalSection (pTxnQ->hContext);
	}

	/* Indicate that no transaction is currently processed in the bus-driver */
	pTxnQ->pCurrTxn = NULL;

	/* Send queued transactions as possible (TRUE indicates we are in external context) */
	txnQ_RunScheduler (pTxnQ, NULL);
}
コード例 #14
0
ファイル: txDataQueue.c プロジェクト: IdeosDev/vendor_ti_wlan
/**
 * \fn     txDataQ_LinkMacFind
 * \brief  Find entry with MAC address
 *
 * \return status
 * \sa     txDataQ_LinkMacFind
 */
TI_STATUS txDataQ_LinkMacFind (TI_HANDLE hTxDataQ, TI_UINT32 *uHlid, TMacAddr tMacAddr)
{
	TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
	int i;
	int j;

	/* Enter critical section to protect links data */
	context_EnterCriticalSection (pTxDataQ->hContext);
	for (i=0; i<LINK_MAC_TABLE_SIZE; i++) {
		if (!pTxDataQ->aLinkMac[i].uValid) {
			/* entry not valid, skip to next entry */
			continue;
		}
		for (j=MAC_ADDR_LEN-1; j>=0; j--) {
			if (pTxDataQ->aLinkMac[i].tMacAddr[j] != tMacAddr[j]) {
				/* different MAC, skip to next entry */
				break;
			}
		}
		if (j < 0) {
			/* Found, return index */
			*uHlid = i;
			context_LeaveCriticalSection (pTxDataQ->hContext);
			return TI_OK;
		}
	}
	context_LeaveCriticalSection (pTxDataQ->hContext);

	/* Not found */
	*uHlid = 0xff; /* for debug */
	return TI_NOK;
}
コード例 #15
0
ファイル: txDataQueue.c プロジェクト: Achotjan/FreeXperia
/** 
 * \fn     txDataQ_FlushLinkQueues
 * \brief  Flush all queues of the specific link
 * 
 * Free all pending packets in link queue
 *
 * \note   
 * \param  hTxDataQ - The object                                          
 * \param  uHlid - Link ID
 * \return void
 * \sa
 */ 
void txDataQ_FlushLinkQueues (TI_HANDLE hTxDataQ, TI_UINT32 uHlid)
{
    TTxDataQ   *pTxDataQ = (TTxDataQ *)hTxDataQ;
    TTxCtrlBlk *pPktCtrlBlk;
    TI_UINT32  uQueId;
    TDataLinkQ *pLinkQ;

    pLinkQ = &pTxDataQ->aDataLinkQ[uHlid]; /* Link queues */

    /* Dequeue and free all queued packets */
    for (uQueId = 0 ; uQueId < pTxDataQ->uNumQueues ; uQueId++)
    {
        while (1)
        {
            context_EnterCriticalSection (pTxDataQ->hContext);
            pPktCtrlBlk = (TTxCtrlBlk *) que_Dequeue (pLinkQ->aQueues[uQueId]);
            context_LeaveCriticalSection (pTxDataQ->hContext);
            if (pPktCtrlBlk == NULL) 
            {
                break;
            }
            txCtrl_FreePacket (pTxDataQ->hTxCtrl, pPktCtrlBlk, TI_NOK);
        }
    }
}
コード例 #16
0
ファイル: timer.c プロジェクト: IdeosDev/vendor_ti_wlan
void tmr_ClearOperQueue (TI_HANDLE hTimerModule)
{
	TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;

	context_EnterCriticalSection (pTimerModule->hContext);
	while (que_Dequeue (pTimerModule->hOperQueue) != NULL) {}
	context_LeaveCriticalSection (pTimerModule->hContext);
}
コード例 #17
0
/** 
 * \fn     txMgmtQ_Xmit
 * \brief  Insert non-data packet for transmission
 * 
 * This function is used by the driver applications to send Tx packets other than the 
 *   regular data traffic, including the following packet types:
*				- Management
*				- EAPOL
*				- NULL
*				- IAPP
 * The managment packets are enqueued to the Mgmt-queue and the others to the Eapol-queue.
 * EAPOL packets may be inserted from the network stack context, so it requires switching 
 *   to the driver's context (after the packet is enqueued).
 * If the selected queue was empty before the packet insertion, the SM is called 
 *   with QUEUES_NOT_EMPTY event (in case of external context, only after the context switch).
 *
 * \note   
 * \param  hTxMgmtQ         - The module's object                                          
 * \param  pPktCtrlBlk      - Pointer to the packet CtrlBlk                                         
 * \param  bExternalContext - Indicates if called from non-driver context                                           
 * \return TI_OK - if the packet was queued, TI_NOK - if the packet was dropped. 
 * \sa     txMgmtQ_QueuesNotEmpty
 */ 
TI_STATUS txMgmtQ_Xmit (TI_HANDLE hTxMgmtQ, TTxCtrlBlk *pPktCtrlBlk, TI_BOOL bExternalContext)
{
    TTxMgmtQ *pTxMgmtQ = (TTxMgmtQ *)hTxMgmtQ;
	TI_STATUS eStatus;
	TI_UINT32 uQueId;
    TI_UINT32 uQueSize;

	/* Always set highest TID for mgmt-queues packets. */
	pPktCtrlBlk->tTxDescriptor.tid = MGMT_QUEUES_TID; 

    /* Select queue asccording to the packet type */
	uQueId = (pPktCtrlBlk->tTxPktParams.uPktType == TX_PKT_TYPE_MGMT) ? QUEUE_TYPE_MGMT : QUEUE_TYPE_EAPOL ;

    /* Enter critical section to protect queue access */
    context_EnterCriticalSection (pTxMgmtQ->hContext);

	/* Enqueue the packet in the appropriate Queue */
    eStatus = que_Enqueue (pTxMgmtQ->aQueues[uQueId], (TI_HANDLE)pPktCtrlBlk);

    /* Get number of packets in current queue */
    uQueSize = que_Size (pTxMgmtQ->aQueues[uQueId]);

    /* Leave critical section */
    context_LeaveCriticalSection (pTxMgmtQ->hContext);

	/* If packet enqueued successfully */
	if (eStatus == TI_OK)
	{
		pTxMgmtQ->tDbgCounters.aEnqueuePackets[uQueId]++;

        /* If selected queue was empty before packet insertion */
        if (uQueSize == 1) 
        {
            /* If called from external context (EAPOL from network), request switch to the driver's context. */
            if (bExternalContext) 
            {
                context_RequestSchedule (pTxMgmtQ->hContext, pTxMgmtQ->uContextId);
            }

            /* If already in the driver's context, call the SM with QUEUES_NOT_EMPTY event. */
            else 
            {
                mgmtQueuesSM(pTxMgmtQ, SM_EVENT_QUEUES_NOT_EMPTY);
            }
        }
	}

	else
    {
        /* If the packet can't be queued so drop it */
        txCtrl_FreePacket (pTxMgmtQ->hTxCtrl, pPktCtrlBlk, TI_NOK);
		pTxMgmtQ->tDbgCounters.aDroppedPackets[uQueId]++;
    }

    return eStatus;
}
コード例 #18
0
/** 
 * \fn     tmr_HandleExpiry
 * \brief  Handles queued expiry events in driver context
 * 
 * This is the Timer module's callback that is registered to the ContextEngine module to be invoked
 *   from the driver task (after requested by tmr_GetExpiry through context_RequestSchedule ()).
 * It dequeues all expiry events from the queue that correlates to the current driver state,
 *   and calls their users callbacks.
 * 
 * \note   
 * \param  hTimerModule - The module object
 * \return void
 * \sa     tmr_GetExpiry
 */ 
void tmr_HandleExpiry (TI_HANDLE hTimerModule)
{
    TTimerModule *pTimerModule = (TTimerModule *)hTimerModule; /* The timer module handle */
    TTimerInfo   *pTimerInfo;      /* The timer handle */     
    TI_BOOL       bTwdInitOccured; /* Indicates if TWD init occured since timer start */

    if (!pTimerModule)
    {
        WLAN_OS_REPORT (("tmr_HandleExpiry(): ERROR - NULL timer!\n"));
        return;
    }

    while (1)
    {
        /* Enter critical section */
        context_EnterCriticalSection (pTimerModule->hContext);
    
        /* If current driver state is Operational, dequeue timer object from Operational-queue */
        if (pTimerModule->bOperState)
        {
            pTimerInfo = (TTimerInfo *) que_Dequeue (pTimerModule->hOperQueue);
        }
    
        /* Else (driver state is NOT-Operational), dequeue timer object from Init-queue */
        else
        {
            pTimerInfo = (TTimerInfo *) que_Dequeue (pTimerModule->hInitQueue);
        }
    
        /* Leave critical section */
        context_LeaveCriticalSection (pTimerModule->hContext);

        /* If no more objects in queue, exit */
        if (!pTimerInfo) 
        {
            return;  /** EXIT Point **/
        }

        /* If current TWD-Init-Count is different than when the timer was started, Init occured. */
        bTwdInitOccured = (pTimerModule->uTwdInitCount != pTimerInfo->uTwdInitCountWhenStarted);

        /* Call specific timer callback function */
        pTimerInfo->fExpiryCbFunc (pTimerInfo->hExpiryCbHndl, bTwdInitOccured);

        /* If the expired timer is periodic, start it again. */
        if (pTimerInfo->bPeriodic) 
        {
            tmr_StartTimer ((TI_HANDLE)pTimerInfo,
                            pTimerInfo->fExpiryCbFunc,
                            pTimerInfo->hExpiryCbHndl,
                            pTimerInfo->uIntervalMsec,
                            pTimerInfo->bPeriodic);
        }
    }
}
コード例 #19
0
ファイル: CmdHndlr.c プロジェクト: blueskycoco/wang-linux
/** 
 * \fn     cmdHndlr_HandleCommands 
 * \brief  Handle queued commands
 * 
 * While there are queued commands, dequeue a command and call the 
 *     commands interpreter (OID or WEXT selected at compile time).
 * If the command processing is not completed in this context (pending), we exit and 
 *     this function is called again upon commnad completion, so it can continue processing 
 *     further queued commands (if any).
 * 
 * \note    
 * \param  hCmdHndlr - The module object
 * \return void
 * \sa     cmdHndlr_InsertCommand, cmdHndlr_Complete
 */
void cmdHndlr_HandleCommands(TI_HANDLE hCmdHndlr)
{
	TCmdHndlrObj *pCmdHndlr = (TCmdHndlrObj *) hCmdHndlr;

	while (1) {
		/* Enter critical section to protect queue access */
		context_EnterCriticalSection(pCmdHndlr->hContext);

		/* Dequeue a command */
		pCmdHndlr->pCurrCmd =
		    (TConfigCommand *) que_Dequeue(pCmdHndlr->hCmdQueue);

		/* If we have got a command */
		if (pCmdHndlr->pCurrCmd) {
			/* Leave critical section */
			context_LeaveCriticalSection(pCmdHndlr->hContext);

			/* Convert to driver structure and execute command */
			pCmdHndlr->pCurrCmd->eCmdStatus =
			    cmdInterpret_convertAndExecute(pCmdHndlr->
							   hCmdInterpret,
							   pCmdHndlr->pCurrCmd);

			/* 
			 *  If command not completed in this context (Async), return.
			 *    (we'll be called back upon command completion) 
			 */
			if (COMMAND_PENDING == pCmdHndlr->pCurrCmd->eCmdStatus) {
				return;
			}

			/* Command was completed so free the wait signal and continue to next command */
			wlanDrvIf_CommandDone(pCmdHndlr->hOs,
					      pCmdHndlr->pCurrCmd->
					      pSignalObject,
					      pCmdHndlr->pCurrCmd->
					      CmdRespBuffer);

			pCmdHndlr->pCurrCmd = NULL;

		}

		/* Else, we don't have commands to handle */
		else {
			/* Indicate that we are not handling commands (before leaving critical section!) */
			pCmdHndlr->bProcessingCmds = TI_FALSE;

			/* Leave critical section */
			context_LeaveCriticalSection(pCmdHndlr->hContext);

			/* Exit (no more work) */
			return;
		}
	}
}
コード例 #20
0
ファイル: txDataQueue.c プロジェクト: Achotjan/FreeXperia
/** 
 * \fn     txDataQ_FreeResources
 * \brief  Free resources per Link and per Ac
 * 
 */ 
void txDataQ_FreeResources (TI_HANDLE hTxDataQ, TTxCtrlBlk *pPktCtrlBlk)
{
    TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;
    TDataResources *pDataRsrc = &pTxDataQ->tDataRsrc;
    TI_UINT32 uHlid = pPktCtrlBlk->tTxDescriptor.hlid;
    TI_UINT32 uAc;

    /* Free TxData resources only if previous allocated by txDataQ_AllocCheckResources */
    if (!IS_TX_CTRL_FLAG_RSRC_ALLOCATED(pPktCtrlBlk)) 
    {
        return;
    }

    /* Enter critical section to protect classifier data and queue access */
    context_EnterCriticalSection (pTxDataQ->hContext);

    /* Extract original AC (saved by txDataQ_AllocCheckResources) from tx ctrl block */
    uAc = GET_TX_CTRL_FLAG_RSRC_AC(pPktCtrlBlk);

    /* new packet, Increment packet in use counters */
    pDataRsrc->uPktInUse_PerAc[uAc]--;
    pDataRsrc->uPktInUse_PerLink[uHlid]--;

    /* Update Effective totals = Sum of Max ( PktInUse_PerAc [uAc],  Min_PerAc[uAc] ), uAc=0..MAX_AC */
    /* no need to calculate Sum of Max on every packet, just small check for this ac only */
    if (pDataRsrc->uPktInUse_PerAc[uAc] >= pDataRsrc->uMinGuarantee_PerAc[uAc]) 
    {
        pDataRsrc->uEffectiveTotal_Ac--;
#ifdef TI_DBG
        /* sanity check */
        if (pDataRsrc->uEffectiveTotal_Ac < pDataRsrc->uEffectiveTotal_Ac_Min ) 
        {
            WLAN_OS_REPORT(("%s: uEffectiveTotal_Ac=%d is below MIN=%d\n", __FUNCTION__, pDataRsrc->uEffectiveTotal_Ac, pDataRsrc->uEffectiveTotal_Ac_Min));
        }
#endif
    }

    /* Update Effective totals = Sum of Max ( PktInUse_PerLik [uHlid],  Min_PerLink[uHlid] ), uHlid=0..MAX_LINK */
    /* no need to calculate Sum of Max on every packet, just small check for this link only*/
    if (pDataRsrc->uPktInUse_PerLink[uHlid] >= pDataRsrc->uMinGuarantee_PerLink) 
    {
        pDataRsrc->uEffectiveTotal_Link--;
#ifdef TI_DBG
        /* sanity check */
        if (pDataRsrc->uEffectiveTotal_Link < pDataRsrc->uEffectiveTotal_Link_Min ) 
        {
            WLAN_OS_REPORT(("%s: uEffectiveTotal_Ac=%d is below MIN=%d\n", __FUNCTION__, pDataRsrc->uEffectiveTotal_Link, pDataRsrc->uEffectiveTotal_Link_Min));
        }
#endif
    }

    /* Leave critical section */
    context_LeaveCriticalSection (pTxDataQ->hContext);
}
コード例 #21
0
ファイル: TxnQueue.c プロジェクト: aleho/ti_wilink
TI_STATUS txnQ_Open (TI_HANDLE       hTxnQ, 
                     TI_UINT32       uFuncId, 
                     TI_UINT32       uNumPrios, 
                     TTxnQueueDoneCb fTxnQueueDoneCb,
                     TI_HANDLE       hCbHandle)
{
    TTxnQObj     *pTxnQ = (TTxnQObj*) hTxnQ;
    TI_UINT32     uNodeHeaderOffset;
    TI_UINT32     i;

    if (uFuncId >= MAX_FUNCTIONS  ||  uNumPrios > MAX_PRIORITY) 
    {
        TRACE2(pTxnQ->hReport, REPORT_SEVERITY_ERROR, ": Invalid Params!  uFuncId = %d, uNumPrios = %d\n", uFuncId, uNumPrios);
        return TI_NOK;
    }

    context_EnterCriticalSection (pTxnQ->hContext);

    /* Save functional driver info */
    pTxnQ->aFuncInfo[uFuncId].uNumPrios       = uNumPrios;
    pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb = fTxnQueueDoneCb;
    pTxnQ->aFuncInfo[uFuncId].hCbHandle       = hCbHandle;
    pTxnQ->aFuncInfo[uFuncId].eState          = FUNC_STATE_STOPPED;
    
    /* Create the functional driver's queues. */
    uNodeHeaderOffset = TI_FIELD_OFFSET(TTxnStruct, tTxnQNode); 
    for (i = 0; i < uNumPrios; i++)
    {
        pTxnQ->aTxnQueues[uFuncId][i] = que_Create (pTxnQ->hOs, pTxnQ->hReport, TXN_QUE_SIZE, uNodeHeaderOffset);
        if (pTxnQ->aTxnQueues[uFuncId][i] == NULL)
        {
            TRACE0(pTxnQ->hReport, REPORT_SEVERITY_ERROR, ": Queues creation failed!\n");
            context_LeaveCriticalSection (pTxnQ->hContext);
            return TI_NOK;
        }
    }

    /* Update functions actual range (to optimize Txn selection loops - see txnQ_SelectTxn) */
    if (uFuncId < pTxnQ->uMinFuncId) 
    {
        pTxnQ->uMinFuncId = uFuncId;
    }
    if (uFuncId > pTxnQ->uMaxFuncId) 
    {
        pTxnQ->uMaxFuncId = uFuncId;
    }

    context_LeaveCriticalSection (pTxnQ->hContext);

    TRACE2(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, ": Function %d registered successfully, uNumPrios = %d\n", uFuncId, uNumPrios);

    return TI_OK;
}
コード例 #22
0
ファイル: txDataQueue.c プロジェクト: IdeosDev/vendor_ti_wlan
/**
 * \fn     txDataQ_LinkMacRemove
 * \brief  Set LinkMac table entry as invalid
 *
 * \return void
 * \sa     txDataQ_LinkMacRemove
 */
void txDataQ_LinkMacRemove (TI_HANDLE hTxDataQ, TI_UINT32 uHlid)
{
	TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;

	if (uHlid >= LINK_MAC_TABLE_SIZE) {
		WLAN_OS_REPORT(("%s: illegal uHlid = %d\n", __FUNCTION__, uHlid));
		return;
	}
	/* Enter critical section to protect links data */
	context_EnterCriticalSection (pTxDataQ->hContext);
	pTxDataQ->aLinkMac[uHlid].uValid = TI_FALSE;
	context_LeaveCriticalSection (pTxDataQ->hContext);
}
コード例 #23
0
ファイル: CmdHndlr.c プロジェクト: Achotjan/FreeXperia
/** 
 * \fn     cmdHndlr_ClearQueue
 * \brief  Clear commands queue
 * 
 * Dequeue and free all queued commands.
 * 
 * \note   
 * \param  hCmdHndlr - The object                                          
 * \return void 
 * \sa     
 */ 
void cmdHndlr_ClearQueue (TI_HANDLE hCmdHndlr)
{
    TCmdHndlrObj    *pCmdHndlr = (TCmdHndlrObj *)hCmdHndlr;
    TConfigCommand  *pCurrCmd;

    /* Dequeue and free all queued commands */
    do {
        context_EnterCriticalSection (pCmdHndlr->hContext);
        pCurrCmd = (TConfigCommand *)que_Dequeue(pCmdHndlr->hCmdQueue);
        context_LeaveCriticalSection (pCmdHndlr->hContext);
        if (pCurrCmd != NULL) {
            /* Just release the semaphore. The command is freed subsequently. */
            os_SignalObjectSet (pCmdHndlr->hOs, pCurrCmd->pSignalObject);
        }
    } while (pCurrCmd != NULL);
}
コード例 #24
0
ファイル: TxnQueue.c プロジェクト: aleho/ti_wilink
/** 
 * \fn     txnQ_TxnDoneCb
 * \brief  Pending Transaction completion CB
 * 
 * Called back by bus-driver upon pending transaction completion in TxnDone context (external!).
 * Enqueue completed transaction in TxnDone queue and call scheduler to send queued transactions.
 * 
 * \note   
 * \param  hTxnQ - The module's object
 * \param  pTxn  - The completed transaction object 
 * \return void
 * \sa     
 */ 
static void txnQ_TxnDoneCb (TI_HANDLE hTxnQ, void *hTxn)
{
    TTxnQObj   *pTxnQ   = (TTxnQObj*)hTxnQ;
    TTxnStruct *pTxn    = (TTxnStruct *)hTxn;
    TI_UINT32   uFuncId = TXN_PARAM_GET_FUNC_ID(pTxn);

#ifdef TI_DBG
    TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_TxnDoneCb()\n");
    if (pTxn != pTxnQ->pCurrTxn) 
    {
        TRACE2(pTxnQ->hReport, REPORT_SEVERITY_ERROR, "txnQ_TxnDoneCb(): CB returned pTxn 0x%x  while pCurrTxn is 0x%x !!\n", pTxn, pTxnQ->pCurrTxn);
    }
#endif

    /* If the function of the completed Txn is waiting for restart */
    if (pTxnQ->aFuncInfo[uFuncId].eState == FUNC_STATE_RESTART) 
    {
        TRACE0(pTxnQ->hReport, REPORT_SEVERITY_INFORMATION, "txnQ_TxnDoneCb(): Handling restart\n");

        /* First, Clear the restarted function queues  */
        txnQ_ClearQueues (hTxnQ, uFuncId);

        /* Call function CB for current Txn with restart indication */
        TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_RECOVERY);
        pTxnQ->aFuncInfo[uFuncId].fTxnQueueDoneCb (pTxnQ->aFuncInfo[uFuncId].hCbHandle, pTxn);
    }

    /* In the normal case (no restart), enqueue completed transaction in TxnDone queue */
    else 
    {
        TI_STATUS eStatus;

        context_EnterCriticalSection (pTxnQ->hContext);
        eStatus = que_Enqueue (pTxnQ->hTxnDoneQueue, (TI_HANDLE)pTxn);
        if (eStatus != TI_OK)
        {
            TRACE3(pTxnQ->hReport, REPORT_SEVERITY_ERROR, "txnQ_TxnDoneCb(): Enqueue failed, pTxn=0x%x, HwAddr=0x%x, Len0=%d\n", pTxn, pTxn->uHwAddr, pTxn->aLen[0]);
        }
        context_LeaveCriticalSection (pTxnQ->hContext);
    }

    /* Indicate that no transaction is currently processed in the bus-driver */
    pTxnQ->pCurrTxn = NULL;

    /* Send queued transactions as possible (TRUE indicates we are in external context) */
    txnQ_RunScheduler (pTxnQ, NULL); 
}
コード例 #25
0
ファイル: txDataQueue.c プロジェクト: IdeosDev/vendor_ti_wlan
/**
 * \fn     txDataQ_LinkMacAdd
 * \brief  Set MAC address for the link id.
 *
  * \return void
 * \sa     txDataQ_LinkMacAdd
 */
TI_STATUS txDataQ_LinkMacAdd (TI_HANDLE hTxDataQ, TI_UINT32 uHlid, TMacAddr tMacAddr)
{
	TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ;

	if (uHlid >= LINK_MAC_TABLE_SIZE) {
		WLAN_OS_REPORT(("%s: illegal uHlid = %d\n", __FUNCTION__, uHlid));
		return TI_NOK;
	}
	/* Enter critical section to protect links data */
	context_EnterCriticalSection (pTxDataQ->hContext);

	pTxDataQ->aLinkMac[uHlid].uValid = TI_TRUE;
	MAC_COPY (pTxDataQ->aLinkMac[uHlid].tMacAddr, tMacAddr);

	context_LeaveCriticalSection (pTxDataQ->hContext);

	return TI_OK;
}
コード例 #26
0
/**
 * \fn     txDataQ_ClearQueues
 * \brief  Clear all queues
 *
 * Dequeue and free all queued packets.
 *
 * \note
 * \param  hTxDataQ - The object
 * \return void
 * \sa
 */
void txDataQ_ClearQueues (TI_HANDLE hTxDataQ)
{
	TTxDataQ   *pTxDataQ = (TTxDataQ *)hTxDataQ;
	TTxCtrlBlk *pPktCtrlBlk;
	TI_UINT32  uQueId;

	/* Dequeue and free all queued packets */
	for (uQueId = 0 ; uQueId < pTxDataQ->uNumQueues ; uQueId++) {
		do {
			context_EnterCriticalSection (pTxDataQ->hContext);
			pPktCtrlBlk = (TTxCtrlBlk *) que_Dequeue(pTxDataQ->aQueues[uQueId]);
			context_LeaveCriticalSection (pTxDataQ->hContext);
			if (pPktCtrlBlk != NULL) {
				txCtrl_FreePacket (pTxDataQ->hTxCtrl, pPktCtrlBlk, TI_NOK);
			}
		} while (pPktCtrlBlk != NULL);
	}
}
コード例 #27
0
/** 
 * \fn     tmr_UpdateDriverState 
 * \brief  Update driver state 
 * 
 * Under critical section, update driver state (operational or not),
 *   and if opertional, clear init queue.
 * Leave critical section and if operational state, request schedule for handling 
 *   timer events in driver context (if any).
 * 
 * \note    
 * \param  hTimerModule - The timer module object
 * \param  bOperState   - TRUE if driver state is now operational, FALSE if not.
 * \return void  
 * \sa     
 */ 
void tmr_UpdateDriverState (TI_HANDLE hTimerModule, TI_BOOL bOperState)
{
    TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;

    if (!pTimerModule)
    {
        WLAN_OS_REPORT (("tmr_UpdateDriverState(): ERROR - NULL timer!\n"));
        return;
    }

    /* Enter critical section */
    context_EnterCriticalSection (pTimerModule->hContext);

    if (bOperState == pTimerModule->bOperState) 
    {
        context_LeaveCriticalSection (pTimerModule->hContext);
        TRACE1(pTimerModule->hReport, REPORT_SEVERITY_ERROR, "tmr_UpdateDriverState(): New bOperState (%d) is as current!\n", bOperState);
        return;
    }

    /* Save new state (TRUE means operational). */
    pTimerModule->bOperState = bOperState;

    /* If new state is operational */
    if (bOperState) 
    {
        /* Increment the TWD initializations counter (for detecting recovery events). */
        pTimerModule->uTwdInitCount++;

        /* Empty the init queue (obsolete). */
        while (que_Dequeue (pTimerModule->hInitQueue) != NULL) {}
    }

    /* Leave critical section */
    context_LeaveCriticalSection (pTimerModule->hContext);

    /* If new state is operational, request switch to driver context for handling timer events */
    if (bOperState) 
    {
        context_RequestSchedule (pTimerModule->hContext, pTimerModule->uContextId);
    }
}
コード例 #28
0
ファイル: txCtrlBlk.c プロジェクト: bluewater-cn/ti_wilink
/****************************************************************************
 *					txCtrlBlk_Free()
 ****************************************************************************
 * DESCRIPTION:	
	Link the freed entry after entry 0, so now it is the first free entry to
	  be allocated.
 ****************************************************************************/
void txCtrlBlk_Free (TI_HANDLE hTxCtrlBlk, TTxCtrlBlk *pCurrentEntry)
{
	TTxCtrlBlkObj   *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk;
	TTxCtrlBlk *pFirstFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[0]);

#ifdef TI_DBG
	/* If the pointed entry is already free, print error and exit (not expected to happen). */
	if (pCurrentEntry->pNextFreeEntry != 0)
	{
		return;
	}
	pTxCtrlBlk->uNumUsedEntries--;
#endif

    /* Protect block freeing from preemption (may be called from external context) */
    context_EnterCriticalSection (pTxCtrlBlk->hContext);

	/* Link the freed entry between entry 0 and the next free entry. */
	pCurrentEntry->pNextFreeEntry   = pFirstFreeEntry->pNextFreeEntry;
	pFirstFreeEntry->pNextFreeEntry = pCurrentEntry;

    context_LeaveCriticalSection (pTxCtrlBlk->hContext);
}
コード例 #29
0
ファイル: txCtrlBlk.c プロジェクト: Achotjan/FreeXperia
/****************************************************************************
 *					txCtrlBlk_Alloc()
 ****************************************************************************
 * DESCRIPTION:
	Allocate a free control-block entry for the current Tx packet's parameters
	  (including the descriptor structure).
	Note that entry 0 in the list is never allocated and points to the
	  first free entry.
 ****************************************************************************/
TTxCtrlBlk *txCtrlBlk_Alloc (TI_HANDLE hTxCtrlBlk)
{
	TTxCtrlBlkObj   *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk;
	TTxCtrlBlk      *pCurrentEntry; /* The pointer of the new entry allocated for the packet. */
	TTxCtrlBlk      *pFirstFreeEntry; /* The first entry just points to the first free entry. */

	pFirstFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[0]);

	/* Protect block allocation from preemption (may be called from external context) */
	context_EnterCriticalSection (pTxCtrlBlk->hContext);

	pCurrentEntry = pFirstFreeEntry->pNextFreeEntry; /* Get free entry. */

#ifdef TI_DBG
	/* If no free entries, print error (not expected to happen) and return NULL. */
	if (pCurrentEntry->pNextFreeEntry == NULL)
	{
		TRACE1(pTxCtrlBlk->hReport, REPORT_SEVERITY_ERROR, "txCtrlBlk_alloc():  No free entry,  UsedEntries=%d\n", pTxCtrlBlk->uNumUsedEntries);
		context_LeaveCriticalSection (pTxCtrlBlk->hContext);
		return NULL;
	}
	pTxCtrlBlk->uNumUsedEntries++;
#endif

	/* Link the first entry to the next free entry. */
	pFirstFreeEntry->pNextFreeEntry = pCurrentEntry->pNextFreeEntry;

	context_LeaveCriticalSection (pTxCtrlBlk->hContext);

	/* Clear the next-free-entry index just as an indication that our entry is not free. */
	pCurrentEntry->pNextFreeEntry = 0;

	pCurrentEntry->tTxPktParams.uFlags = 0;
	pCurrentEntry->tTxPktParams.uHeadroomSize = 0;

	return pCurrentEntry;
}
コード例 #30
0
ファイル: timer.c プロジェクト: bluewater-cn/ti_wilink
/**
 * \fn     tmr_Destroy
 * \brief  Destroy the module.
 *
 * Free the module's queues and object.
 *
 * \note   This is NOT a specific timer destruction! (see tmr_DestroyTimer)
 * \param  hTimerModule - The module object
 * \return TI_OK on success or TI_NOK on failure
 * \sa     tmr_Create
 */
TI_STATUS tmr_Destroy (TI_HANDLE hTimerModule)
{
    TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;

    /* Alert if there are still timers that were not destroyed */
    if (pTimerModule->uTimersCount)
    {
    }

    /* Clear queues (critical section is used inside these functions) */
//    tmr_ClearInitQueue (hTimerModule);
//    tmr_ClearOperQueue (hTimerModule);

    /* Destroy the module's queues (protect in critical section)) */
    context_EnterCriticalSection (pTimerModule->hContext);
    que_Destroy (pTimerModule->hInitQueue);
    que_Destroy (pTimerModule->hOperQueue);
    context_LeaveCriticalSection (pTimerModule->hContext);

    /* free module object */
    os_memoryFree (pTimerModule->hOs, pTimerModule, sizeof(TTimerModule));

    return TI_OK;
}