/***********************************************************************
 *                        idle_to_selfWait
 ***********************************************************************
DESCRIPTION: 


INPUT:   

OUTPUT:

RETURN:     TI_OK on success, TI_NOK otherwise

************************************************************************/
static TI_STATUS idle_to_selfWait (void *pData)
{
	conn_t    *pConn = (conn_t *)pData;
    TI_UINT16  randomTime;

    siteMgr_join (pConn->hSiteMgr);

    /* get a randomTime that is constructed of the lower 13 bits ot the system time to 
       get a MS random time of ~8000 ms */
    randomTime = os_timeStampMs (pConn->hOs) & 0x1FFF;

    /* Update current BSS connection type and mode */
    currBSS_updateConnectedState (pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT);

    tmr_StartTimer (pConn->hConnTimer,
                    conn_timeout,
                    (TI_HANDLE)pConn,
                    pConn->timeout + randomTime,
                    TI_FALSE);

	/*  Notify that the driver is associated to the supplicant\IP stack. */
    EvHandlerSendEvent (pConn->hEvHandler, IPC_EVENT_ASSOCIATED, NULL, 0);

    return TI_OK;
}
Exemple #2
0
/*
 * \brief	Handle the Fw Status information
 *
 * \param  hFwEvent  - FwEvent Driver handle
 * \return void
 *
 * \par Description
 * This function is called from fwEvent_Handle on a sync read, or from TwIf as a CB on an async read.
 * It calls fwEvent_CallHandlers to handle the triggered interrupts.
 *
 * \sa fwEvent_Handle
 */
static ETxnStatus fwEvent_SmHandleEvents (TfwEvent *pFwEvent)
{
	ETxnStatus eStatus;

	/* Save delta between driver and FW time (needed for Tx packets lifetime) */
	pFwEvent->uFwTimeOffset = (os_timeStampMs (pFwEvent->hOs) * 1000) -
	                          ENDIAN_HANDLE_LONG (pFwEvent->tFwStatusTxn.tFwStatus.fwLocalTime);

#ifdef HOST_INTR_MODE_LEVEL
	/* Acknowledge the host interrupt for LEVEL mode (must be after HINT_STT_CLR register clear on read) */
	os_InterruptServiced (pFwEvent->hOs);
#endif

	/* Save the interrupts status retreived from the FW */
	pFwEvent->uEventVector = pFwEvent->tFwStatusTxn.tFwStatus.intrStatus;

	/* Mask unwanted interrupts */
	pFwEvent->uEventVector &= pFwEvent->uEventMask;

	/* Call the interrupts handlers */
	eStatus = fwEvent_CallHandlers (pFwEvent);


	/* Return the status of the handlers processing (complete, pending or error) */
	return eStatus;
}
/**
*
*
* \b Description:
*
* Update the Switch Channel command parameters.
 * Request SCR and wait for SCR return.
 * if tx status suspend
 *  update regulatory Domain
 *  update tx
 *  start periodic timer

*
* \b ARGS:
*
*  I   - pData - pointer to the SwitchChannel SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
*
*************************************************************************/
static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData)
{
	switchChannel_t             *pSwitchChannel = (switchChannel_t*)pData;
	EScrClientRequestStatus     scrStatus;
	EScePendReason              scrPendReason;

	if (pSwitchChannel == NULL) {
		return TI_NOK;
	}


	/* Save the TS when requesting SCR */
	pSwitchChannel->SCRRequestTimestamp = os_timeStampMs(pSwitchChannel->hOs);

	scrStatus = scr_clientRequest(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL,
	                              SCR_RESOURCE_SERVING_CHANNEL, &scrPendReason);
	if ((scrStatus != SCR_CRS_RUN) && (scrStatus != SCR_CRS_PEND)) {
		return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel));

	}
	if (scrStatus == SCR_CRS_RUN) {
		switchChannel_scrStatusCB(pSwitchChannel, scrStatus, SCR_RESOURCE_SERVING_CHANNEL, scrPendReason);
	} else if ((scrPendReason==SCR_PR_OTHER_CLIENT_RUNNING) ||
	           (scrPendReason==SCR_PR_DIFFERENT_GROUP_RUNNING) ) {  /* No use to wait for the SCR, invoke FAIL */
		return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel));
	}
	/* wait for the SCR callback function to be called */
	return TI_OK;

}
/**
*
*
* \b Description:
*
* This function is called once SwitchChannel command was received and the SCR
 * request returned with reason RUN.
 * In this case perform the following:
 *  Set CMD to FW


*
* \b ARGS:
*
*  I   - pData - pointer to the SwitchChannel SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
*
*************************************************************************/
static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData)
{
	switchChannel_t         *pSwitchChannel = (switchChannel_t *)pData;
	TSwitchChannelParams    pSwitchChannelCmd;
	TI_UINT32                   switchChannelTimeDuration;
	paramInfo_t             param;

	if (pSwitchChannel == NULL) {
		return TI_NOK;
	}

	param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM;
	siteMgr_getParam(pSwitchChannel->hSiteMgr, &param);

	switchChannelTimeDuration = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount * param.content.beaconInterval * 1024 / 1000;
	if (  (switchChannelTimeDuration!=0) &&
	        ((os_timeStampMs(pSwitchChannel->hOs) - pSwitchChannel->SCRRequestTimestamp) >= switchChannelTimeDuration )) {  /* There's no time to perfrom the SCC, set the Count to 1 */
		pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 1;
	}

	apConn_indicateSwitchChannelInProgress(pSwitchChannel->hApConn);

	pSwitchChannelCmd.channelNumber = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
	pSwitchChannelCmd.switchTime    = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount;
	pSwitchChannelCmd.txFlag        = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode;
	pSwitchChannelCmd.flush         = 0;
	TWD_CmdSwitchChannel (pSwitchChannel->hTWD, &pSwitchChannelCmd);


	return TI_OK;

}
/***********************************************************************
 *                        txCtrlParams_setAdmissionCtrlParams
 ***********************************************************************
DESCRIPTION:    This function is called for add/delete a tspec in order
				to update parameters.

INPUT:			hTxCtrl - handale to the ts data object
				acId - the AC of the tspec
				mediumTime	- tha alocated medium time for this UP 
				minimumPHYRate - the min phy rate to send a packet of this UP
				admFlag - indicate if the its addition or deletion of tspec 

OUTPUT:     None

RETURN:     void
************************************************************************/
TI_STATUS txCtrlParams_setAdmissionCtrlParams(TI_HANDLE hTxCtrl, TI_UINT8 acId, TI_UINT16 mediumTime, 
											  TI_UINT32 minimumPHYRate, TI_BOOL admFlag)
{
	txCtrl_t *pTxCtrl = (txCtrl_t *)hTxCtrl;
	TI_UINT32	i;

	if(admFlag == TI_TRUE) 
	{
		/* tspec added */
		pTxCtrl->mediumTime[acId] = mediumTime;
        pTxCtrl->admissionState[acId] = AC_ADMITTED;
		pTxCtrl->useAdmissionAlgo[acId] = TI_TRUE;
		pTxCtrl->lastCreditCalcTimeStamp[acId] = os_timeStampMs(pTxCtrl->hOs);
		pTxCtrl->credit[acId] = mediumTime;
	}
	else
	{
		/* tspaec deleted */
		pTxCtrl->mediumTime[acId] = 0;
        pTxCtrl->admissionState[acId] = AC_NOT_ADMITTED;
		pTxCtrl->useAdmissionAlgo[acId] = TI_FALSE;
		pTxCtrl->lastCreditCalcTimeStamp[acId] = 0;
		pTxCtrl->credit[acId] = 0;
	}

	/* Update the Tx queues mapping after admission change. */
	txCtrl_UpdateQueuesMapping (hTxCtrl);
	
	/* If the timer was not enabled in registry than we will never set it */
	if (pTxCtrl->bCreditCalcTimerEnabled)
	{
    	/* enable disable credit calculation timer */
    	for (i = 0; i < MAX_NUM_OF_AC; i++)
    	{
    		if (pTxCtrl->useAdmissionAlgo[i])
    		{
    			if (!pTxCtrl->bCreditCalcTimerRunning)
    			{
    				pTxCtrl->bCreditCalcTimerRunning = TI_TRUE;
                    tmr_StartTimer (pTxCtrl->hCreditTimer,
                                    calcCreditFromTimer,
                                    (TI_HANDLE)pTxCtrl,
                                    pTxCtrl->creditCalculationTimeout, 
                                    TI_TRUE);
    			}
    			
    			return TI_OK;
    		}
    	}
    
    	/* in all queues useAdmissionAlgo is not TRUE, so stop timer if running */
        if (pTxCtrl->bCreditCalcTimerRunning)
        {
            tmr_StopTimer (pTxCtrl->hCreditTimer);
            pTxCtrl->bCreditCalcTimerRunning = TI_FALSE;
        }
    }

	return TI_OK;
}
Exemple #6
0
/*
 * \brief	Handle the Fw Status information 
 * 
 * \param  hFwEvent  - FwEvent Driver handle
 * \return void
 * 
 * \par Description
 * This function is called from fwEvent_Handle on a sync read, or from TwIf as a CB on an async read.
 * It calls fwEvent_CallHandlers to handle the triggered interrupts.
 * 
 * \sa fwEvent_Handle
 */
static ETxnStatus fwEvent_SmHandleEvents (TfwEvent *pFwEvent)
{
    ETxnStatus eStatus;
    CL_TRACE_START_L4();

    /* Save delta between driver and FW time (needed for Tx packets lifetime) */
    pFwEvent->uFwTimeOffset = (os_timeStampMs (pFwEvent->hOs) * 1000) - 
                              ENDIAN_HANDLE_LONG (pFwEvent->tFwStatusTxn.tFwStatus.fwLocalTime);

#ifdef HOST_INTR_MODE_LEVEL
    /* Acknowledge the host interrupt for LEVEL mode (must be after HINT_STT_CLR register clear on read) */
    os_InterruptServiced (pFwEvent->hOs);
#endif

    /* Save the interrupts status retreived from the FW */
    pFwEvent->uEventVector = pFwEvent->tFwStatusTxn.tFwStatus.intrStatus;

    /* Mask unwanted interrupts */
    pFwEvent->uEventVector &= pFwEvent->uEventMask;

    /* Call the interrupts handlers */
    eStatus = fwEvent_CallHandlers (pFwEvent);

    TRACE5(pFwEvent->hReport, REPORT_SEVERITY_INFORMATION, "fwEvent_SmHandleEvents: Status=%d, EventVector=0x%x, IntrPending=%d, NumPendHndlrs=%d, FwTimeOfst=%d\n", eStatus, pFwEvent->uEventVector, pFwEvent->bIntrPending, pFwEvent->uNumPendHndlrs, pFwEvent->uFwTimeOffset);
    CL_TRACE_END_L4("tiwlan_drv.ko", "CONTEXT", "FwEvent", "");

    /* Return the status of the handlers processing (complete, pending or error) */
    return eStatus;
} 
TI_STATUS TrafficMonitor_Start(TI_HANDLE hTrafficMonitor)
{
	TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
	TrafficAlertElement_t *AlertElement;
	TI_UINT32 CurentTime;


	if (TrafficMonitor == NULL)
		return TI_NOK;

	/*starts the bandwidth TIMER*/
	if (!TrafficMonitor->Active) { /*To prevent double call to timer start*/
		TrafficMonitor_UpdateDownTrafficTimerState (TrafficMonitor);
	}

	AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
	CurentTime = os_timeStampMs(TrafficMonitor->hOs);

	/* go over all the Down elements and reload the timer*/
	while (AlertElement) {
		if (AlertElement->CurrentState != ALERT_WAIT_FOR_RESET) {
			AlertElement->EventCounter = 0;
			AlertElement->TimeOut = AlertElement->TimeIntervalMs + CurentTime;
		}
		AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
	}
	TrafficMonitor->Active = TI_TRUE;

	return TI_OK;
}
/**
 * \\n
 * \date 09-November-2005\n
 * \brief Starts a measurement operation.\n
 *
 * Function Scope \e Public.\n
 * \param hMacServices - handle to the MacServices object.\n
 * \param pMsrRequest - a structure containing measurement parameters.\n
 * \param timeToRequestexpiryMs - the time (in milliseconds) the measurement SRV has to start the request.\n
 * \param cmdResponseCBFunc - callback function to used for command response.\n
 * \param cmdResponseCBObj - handle to pass to command response CB.\n
 * \param cmdCompleteCBFunc - callback function to be used for command complete.\n
 * \param cmdCompleteCBObj - handle to pass to command complete CB.\n
 * \return TI_OK if successful (various, TBD codes if not).\n
 */
TI_STATUS MacServices_measurementSRV_startMeasurement( TI_HANDLE hMacServices,
        TMeasurementRequest* pMsrRequest,
        TI_UINT32 timeToRequestExpiryMs,
        TCmdResponseCb cmdResponseCBFunc,
        TI_HANDLE cmdResponseCBObj,
        TMeasurementSrvCompleteCb cmdCompleteCBFunc,
        TI_HANDLE cmdCompleteCBObj )
{
	measurementSRV_t* pMeasurementSRV = (measurementSRV_t*)((MacServices_t*)hMacServices)->hMeasurementSRV;
	TI_INT32 i;

#ifdef TI_DBG
	measurementSRVPrintRequest( (TI_HANDLE)pMeasurementSRV, pMsrRequest );
#endif

	/* mark that request is in progress */
	pMeasurementSRV->bInRequest = TI_TRUE;

	/* mark to send NULL data when exiting driver mode (can be changed to TI_FALSE
	   only when explictly stopping the measurement */
	pMeasurementSRV->bSendNullDataWhenExitPs = TI_TRUE;

	/* Nullify return status */
	pMeasurementSRV->returnStatus = TI_OK;

	/* copy request parameters */
	os_memoryCopy (pMeasurementSRV->hOS,
	               (void *)&pMeasurementSRV->msrRequest,
	               (void *)pMsrRequest,
	               sizeof(TMeasurementRequest));

	/* Mark the current time stamp and the duration to start to cehck expiry later */
	pMeasurementSRV->requestRecptionTimeStampMs = os_timeStampMs( pMeasurementSRV->hOS );
	pMeasurementSRV->timeToRequestExpiryMs = timeToRequestExpiryMs;

	/* copy callbacks */
	pMeasurementSRV->commandResponseCBFunc = cmdResponseCBFunc;
	pMeasurementSRV->commandResponseCBObj = cmdResponseCBObj;
	pMeasurementSRV->measurmentCompleteCBFunc = cmdCompleteCBFunc;
	pMeasurementSRV->measurementCompleteCBObj = cmdCompleteCBObj;

	/* initialize reply */
	pMeasurementSRV->msrReply.numberOfTypes = pMsrRequest->numberOfTypes;
	for ( i = 0; i < pMsrRequest->numberOfTypes; i++ ) {
		pMeasurementSRV->msrReply.msrTypes[ i ].msrType = pMeasurementSRV->msrRequest.msrTypes[ i ].msrType;
		pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_OK;
	}

	/* nullify the pending CBs bitmap */
	pMeasurementSRV->pendingParamCBs = 0;

	/* send a start measurement event to the SM */
	measurementSRVSM_SMEvent( (TI_HANDLE)pMeasurementSRV, &(pMeasurementSRV->SMState),
	                          MSR_SRV_EVENT_MEASURE_START_REQUEST );

	/* mark that request has been sent */
	pMeasurementSRV->bInRequest = TI_FALSE;

	return pMeasurementSRV->returnStatus;
}
Exemple #9
0
/*
 * \brief	Called when a command timeout occur
 *
 * \param  hCmdQueue - Handle to CmdQueue
 * \return TI_OK
 *
 * \par Description
 *
 * \sa cmdQueue_Init, cmdMbox_TimeOut
 */
TI_STATUS cmdQueue_Error (TI_HANDLE hCmdQueue, TI_UINT32 command, TI_UINT32 status, void *param)
{
	TCmdQueue* pCmdQueue = (TCmdQueue*)hCmdQueue;

	if (status == CMD_STATUS_UNKNOWN_CMD)
	{
		TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR , "cmdQueue_Error: Unknown Cmd  (%d)\n", command);
	}
	else if (status == CMD_STATUS_UNKNOWN_IE)
	{
		TRACE4( pCmdQueue->hReport, REPORT_SEVERITY_CONSOLE, "cmdQueue_Error: Unknown IE, cmdType : %d (%d) IE: %d (%d)\n",
		        command,
		        command,
		        (param) ? *((TI_UINT16 *) param) : 0,
		        (param) ? *((TI_UINT16 *) param) : 0
		      );

		WLAN_OS_REPORT(("cmdQueue_Error: Unknown IE, cmdType : %s (%d) IE: %s (%d)\n",
		                cmdQueue_GetCmdString (command),
		                command,
		                (param) ? cmdQueue_GetIEString (command, *((TI_UINT16 *) param)) : "",
		                *((TI_UINT16 *) param)));
	}
	else
	{
		TRACE1(pCmdQueue->hReport, REPORT_SEVERITY_ERROR , "cmdQueue_Error: CmdMbox status is %d\n", status);
	}

	if (status != CMD_STATUS_UNKNOWN_CMD && status != CMD_STATUS_UNKNOWN_IE)
	{
#ifdef TI_DBG

		TCmdQueueNode* pHead = &pCmdQueue->aCmdQueue[pCmdQueue->head];
		TI_UINT32 TimeStamp = os_timeStampMs(pCmdQueue->hOs);

		WLAN_OS_REPORT(("cmdQueue_Error: **ERROR**  Command Occured \n"
		                "                                        Cmd = %s %s, Len = %d \n"
		                "                                        NumOfCmd = %d\n"
		                "                                        MAC TimeStamp on timeout = %d\n",
		                cmdQueue_GetCmdString(pHead->cmdType),
		                (pHead->aParamsBuf) ? cmdQueue_GetIEString(pHead->cmdType, *(TI_UINT16 *)pHead->aParamsBuf) : "",
		                pHead->uParamsLen,
		                pCmdQueue->uNumberOfCommandInQueue,
		                TimeStamp));

		/* Print The command that was sent before the timeout occur */
		cmdQueue_PrintHistory(pCmdQueue, CMDQUEUE_HISTORY_DEPTH);

#endif /* TI_DBG */

		/* preform Recovery */
		if (pCmdQueue->fFailureCb)
		{
			pCmdQueue->fFailureCb (pCmdQueue->hFailureCb, TI_NOK);
		}
	}

	return TI_OK;
}
/***********************************************************************
 *                        TrafficMonitor_Event
 ***********************************************************************
DESCRIPTION: this function is called for every event that was requested from the Tx or Rx
             The function preformes update of the all the relevant Alert in the system
             that corresponds to the event. checks the Alert Status due to this event.



INPUT:          hTrafficMonitor -       Traffic Monitor the object.

            Count - evnet count.
            Mask - the event mask that That triggered this function.

            MonitorModuleType Will hold the module type from where this function was called.

OUTPUT:

RETURN:

************************************************************************/
void TrafficMonitor_Event(TI_HANDLE hTrafficMonitor,int Count,TI_UINT16 Mask,TI_UINT32 MonitorModuleType)
{
	TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
	TrafficAlertElement_t *AlertElement;
	TI_UINT32 activeTrafDownEventsNum = 0;
	TI_UINT32 trafficDownMinTimeout = 0xFFFFFFFF;
	TI_UINT32 uCurentTS;

	if (TrafficMonitor == NULL)
		return;

	if (!TrafficMonitor->Active)
		return;

	uCurentTS = os_timeStampMs(TrafficMonitor->hOs);

	/* for BW calculation */
	if (MonitorModuleType == RX_TRAFF_MODULE) {
		if (Mask & DIRECTED_FRAMES_RECV) {
			TrafficMonitor_updateBW(&TrafficMonitor->DirectRxFrameBW, uCurentTS);
		}
	} else if (MonitorModuleType == TX_TRAFF_MODULE) {
		if (Mask & DIRECTED_FRAMES_XFER) {
			TrafficMonitor_updateBW(&TrafficMonitor->DirectTxFrameBW, uCurentTS);
		}
	} else {
		return; /* module type does not exist, error return */
	}

	AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);

	/* go over all the elements and check for alert */
	while (AlertElement) {
		if (AlertElement->CurrentState != ALERT_WAIT_FOR_RESET) {
			if (AlertElement->MonitorMask[MonitorModuleType] & Mask) {
				AlertElement->ActionFunc(AlertElement,Count);
				if (AlertElement->Direction == TRAFF_UP) {
					isThresholdUp(AlertElement, uCurentTS);
				}
			}

			if ((AlertElement->Direction == TRAFF_DOWN) && (AlertElement->Trigger == TRAFF_EDGE) && (AlertElement->CurrentState == ALERT_OFF) && (AlertElement->Enabled == TI_TRUE)) {
				/* Increase counter of active traffic down events */
				activeTrafDownEventsNum++;

				/* Search for the alert with the most short Interval time - will be used to start timer */
				if ((AlertElement->TimeIntervalMs) < (trafficDownMinTimeout))
					trafficDownMinTimeout = AlertElement->TimeIntervalMs;
			}

		}
		AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
	}

	TrafficMonitor_ChangeDownTimerStatus (TrafficMonitor,activeTrafDownEventsNum,trafficDownMinTimeout);

}
Exemple #11
0
/**
 * \brief	Starts the timer guarding the waiting for a missing packet
 *
 * \param	uTid	index of TID timer to start
 */
static void StartMissingPktTimer(TRxQueue *pRxQueue, TI_UINT8 uTid)
{
	/* request to clear this TID's queue */
	pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uTid].uMissingPktTimeStamp = os_timeStampMs(pRxQueue->hOs);

	/* start timer (if not started already) */
	if ( pRxQueue->uMissingPktTimerClient == TID_CLIENT_NONE ) {
		tmr_StartTimer (pRxQueue->hMissingPktTimer, MissingPktTimeout, pRxQueue, BA_SESSION_TIME_TO_SLEEP, TI_FALSE);
		pRxQueue->uMissingPktTimerClient = uTid;
	}
}
/***********************************************************************
 *                        TrafficMonitor_GetFrameBandwidth
 ***********************************************************************
DESCRIPTION: Returns the total direct frames in the Rx and Tx per second.

INPUT:          hTrafficMonitor -       Traffic Monitor the object.


OUTPUT:

RETURN:     Total BW
************************************************************************/
int TrafficMonitor_GetFrameBandwidth(TI_HANDLE hTrafficMonitor)
{
	TrafficMonitor_t 	*pTrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
	TI_UINT32 			uCurentTS;

	if (pTrafficMonitor == NULL)
		return TI_NOK;

	uCurentTS = os_timeStampMs(pTrafficMonitor->hOs);

	/* Calculate BW for Rx & Tx */
	return ( TrafficMonitor_calcBW(&pTrafficMonitor->DirectRxFrameBW, uCurentTS) +
	         TrafficMonitor_calcBW(&pTrafficMonitor->DirectTxFrameBW, uCurentTS) );
}
Exemple #13
0
void sendDataPacket (TI_HANDLE hOs)
{
    TI_UINT32       i;
	TTxCtrlBlk *    pPktCtrlBlk;
    TI_UINT8 *      pPktBuf;
    TEthernetHeader tEthHeader;
	char SrcBssid[6] = {0x88,0x88,0x88,0x88,0x88,0x88};
	char DesBssid[6] = {0x22,0x22,0x22,0x22,0x22,0x22};

	/* Allocate a TxCtrlBlk for the Tx packet and save timestamp, length and packet handle */
    pPktCtrlBlk = TWD_txCtrlBlk_Alloc (tmp_hTWD);

	if( NULL == pPktCtrlBlk )
	{
        os_printf("\n sendDataPacket() : pPktCtrlBlk returned as NULL from TWD_txCtrlBlk_Alloc() ");
        return;
	}

    pPktCtrlBlk->tTxDescriptor.startTime = os_timeStampMs (hOs);
    pPktCtrlBlk->tTxDescriptor.length    = (TI_UINT16)packetLength + ETHERNET_HDR_LEN;
    pPktCtrlBlk->tTxDescriptor.tid       = 0;
    pPktCtrlBlk->tTxPktParams.uPktType   = TX_PKT_TYPE_ETHER;

    /* Allocate buffer with headroom for getting the IP header in a 4-byte aligned address */
    pPktBuf = txCtrl_AllocPacketBuffer (tmp_hTxCtrl, pPktCtrlBlk, packetLength + ETHERNET_HDR_LEN + 2);

    /* Prepare Ethernet header */
    tEthHeader.type = HTOWLANS(ETHERTYPE_IP);
    MAC_COPY (tEthHeader.src, SrcBssid);
    MAC_COPY (tEthHeader.dst, DesBssid);

	if( pPktBuf )
	{
	    os_memoryCopy (hOs, pPktBuf + 2, &tEthHeader, ETHERNET_HDR_LEN);

        /* Build BDL */
        BUILD_TX_TWO_BUF_PKT_BDL (pPktCtrlBlk,
                                  pPktBuf + 2,
                                  ETHERNET_HDR_LEN,
                                  pPktBuf + 2 + ETHERNET_HDR_LEN,
                                  packetLength)

        /* Fill data buffer with incremented numbers */
        for (i = 0; i < packetLength; i++)
        {
            *(pPktBuf + 2 + ETHERNET_HDR_LEN + i) = i;
        }
	}
	else
	{
/*
 * ----------------------------------------------------------------------------
 * Function : whalCtrl_RecoveryEnded
 *
 * Input    : 
 * Output   :
 * Process  :
 *		aanouce all the modules about the end of the recovery proccess.
 * Note(s)  :  Done
 * -----------------------------------------------------------------------------
 */
void whalCtrl_RecoveryEnded(TI_HANDLE hWhalCtrl)
{
	WHAL_CTRL *pWhalCtrl = (WHAL_CTRL *)hWhalCtrl;

	/*Change the State of the mboxQueue and the interrupt Module and 
	After recovery we should enable back all interrupts according to the last interrupt shadow mask*/
	whalCtrl_exitFromInitMode(hWhalCtrl);
    
    /* 
    Indicates the MboxQueue that Reconfig Ended in Order To Call the CallBacks
	That Was saved before the recovery process started 
	*/
	CmdQueue_EndReconfig(((TnetwDrv_t*)pWhalCtrl->hTNETW_Driver)->hCmdQueue);
	
	WLAN_REPORT_INFORMATION(pWhalCtrl->hReport, HAL_CTRL_MODULE_LOG,
							 ("whalCtrl_ReConfig: End  (%d)\n", os_timeStampMs(pWhalCtrl->hOs)));
}
Exemple #15
0
/****************************************************************************************
 *                               dummyPktReqCB                                          *
 ****************************************************************************************
DESCRIPTION: Callback for the TWD_OWN_EVENT_DUMMY_PKT_REQ event - transmits a dummy
             packet

INPUT:      - hTxMgmtQ      - Handle to the TxMgmtQ module
            - str			- Buffer containing the event data
            - strLen        - Event data length
OUTPUT:
RETURN:    void.\n
****************************************************************************************/
void dummyPktReqCB(TI_HANDLE hTxMgmtQ, char* str , TI_UINT32 strLen)
{
	TTxMgmtQ *pTxMgmtQ = (TTxMgmtQ*)hTxMgmtQ;
    TTxCtrlBlk* pTxCtrlBlk;
    void* pPayload;
    const TI_UINT16 uDummyPktBufLen = 1400;
    TI_STATUS status;

    /* Allocate control block for dummy packet */
    pTxCtrlBlk = TWD_txCtrlBlk_Alloc(pTxMgmtQ->hTWD);
    if (NULL == pTxCtrlBlk) {
        TRACE0(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, "dummyPktReqCB: TxCtrlBlk allocation failed!\n");
        return;
    }

    /* Allocate payload buffer */
    pPayload  = txCtrl_AllocPacketBuffer(pTxMgmtQ->hTxCtrl, pTxCtrlBlk, WLAN_HDR_LEN + uDummyPktBufLen);
    if (NULL == pPayload)
    {
        TRACE0(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, "dummyPktReqCB: Packet buffer allocation failed!\n");
        TWD_txCtrlBlk_Free (pTxMgmtQ->hTWD, pTxCtrlBlk);
        return;
    }

	/* Set packet parameters */
    {
		pTxCtrlBlk->tTxDescriptor.startTime = os_timeStampMs(pTxMgmtQ->hOs);

		/* Mark as a Dummy Blocks Packet */
		pTxCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_DUMMY_BLKS;

		BUILD_TX_TWO_BUF_PKT_BDL (pTxCtrlBlk, pTxCtrlBlk->aPktHdr, WLAN_HDR_LEN, pPayload, uDummyPktBufLen);
    }

    pTxMgmtQ->tDbgCounters.uDummyPackets++;

    /* Enqueue packet in the management-queues and run the scheduler. */
    status = txMgmtQ_Xmit(pTxMgmtQ, pTxCtrlBlk, TI_FALSE);

    if (TI_NOK == status)
    {
        TRACE0(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, "dummyPktReqCB: xmit failed!\n");
    }
}
void TrafficMonitor_Init (TStadHandlesList *pStadHandles, TI_UINT32 BWwindowMs)
{
	TrafficMonitor_t *TrafficMonitor = (TrafficMonitor_t *)(pStadHandles->hTrafficMon);
	TI_UINT32 uCurrTS = os_timeStampMs (TrafficMonitor->hOs);

	/* Create the base threshold timer that will serve all the down thresholds*/
	TrafficMonitor->hTrafficMonTimer = tmr_CreateTimer (pStadHandles->hTimer);

	TrafficMonitor->Active = TI_FALSE;

	TrafficMonitor->hRxData = pStadHandles->hRxData;
	TrafficMonitor->hTxCtrl = pStadHandles->hTxCtrl;
	TrafficMonitor->hTimer  = pStadHandles->hTimer;

	/*Init All the bandwidth elements in the system */
	os_memoryZero(TrafficMonitor->hOs,&TrafficMonitor->DirectTxFrameBW,sizeof(BandWidth_t));
	os_memoryZero(TrafficMonitor->hOs,&TrafficMonitor->DirectRxFrameBW,sizeof(BandWidth_t));
	TrafficMonitor->DirectRxFrameBW.auFirstEventsTS[0] = uCurrTS;
	TrafficMonitor->DirectTxFrameBW.auFirstEventsTS[0] = uCurrTS;

	/*Registering to the RX module for notification.*/
	TrafficMonitor->RxRegReqHandle = rxData_RegNotif (pStadHandles->hRxData,
	                                 DIRECTED_FRAMES_RECV,
	                                 TrafficMonitor_Event,
	                                 TrafficMonitor,
	                                 RX_TRAFF_MODULE);

	/*Registering to the TX module for notification .*/
	TrafficMonitor->TxRegReqHandle = txCtrlParams_RegNotif (pStadHandles->hTxCtrl,
	                                 DIRECTED_FRAMES_XFER,
	                                 TrafficMonitor_Event,
	                                 TrafficMonitor,
	                                 TX_TRAFF_MODULE);

	TrafficMonitor->DownTimerEnabled = TI_FALSE;
	TrafficMonitor->trafficDownTestIntervalPercent = MIN_INTERVAL_PERCENT;

#ifdef TRAFF_TEST
	TestTrafficMonitor = TrafficMonitor;
	TestEventTimer = tmr_CreateTimer (pStadHandles->hTimer);
	tmr_StartTimer (TestEventTimer, TestEventFunc, (TI_HANDLE)TrafficMonitor, 5000, TI_TRUE);
#endif
}
/*
 * ----------------------------------------------------------------------------
 * Function : whalCtrl_ReConfig
 *
 * Input    : 
 * Output   :
 * Process  :
 *      Do firmware download 
 *      Run the firmware
 *      Configure stage (ConfigHw)
 *      Re-Join if needed
 * Note(s)  :  Done
 * -----------------------------------------------------------------------------
 */
int whalCtrl_ReConfig (TI_HANDLE hWhalCtrl, int DoReJoin)
{
    WHAL_CTRL    *pWhalCtrl = (WHAL_CTRL *)hWhalCtrl;
    WlanParams_T *pWlanParams = whal_ParamsGetWlanParams (pWhalCtrl->pWhalParams);
    int           Stt;
    
    if (!pWlanParams->RecoveryEnable)
    {
        WLAN_OS_REPORT(("Recovery is disabled in registry, abort recovery process\n"));
        return OK;
    }
    
  #if 0
    /* L.M. PATCH for card eject */
    if (!whalBus_FwCtrl_isCardIn (pWhalCtrl->pHwCtrl->hWhalBus))
    {
        WLAN_REPORT_REPLY (pWhalCtrl->hReport, HAL_CTRL_MODULE_LOG,
                          ("whalCtrl_ReConfig: card was removed => not proceeding\n"));
        return OK;
    }
  #endif/*_WINDOWS*/

    /*
     * Initiate the wlan hardware (FW download).
     * -----------------------------------------
     */
    WLAN_REPORT_INFORMATION (pWhalCtrl->hReport, HAL_CTRL_MODULE_LOG,
                             ("whalCtrl_ReConfig: Start(%d)\n", os_timeStampMs (pWhalCtrl->hOs)));
    Stt = whal_hwCtrl_Initiate (pWhalCtrl->pHwCtrl);
    if (Stt != OK)
    {
        WLAN_REPORT_ERROR (pWhalCtrl->hReport, HAL_CTRL_MODULE_LOG,
            ("whalCtrl_ReConfig: whal_hwCtrl_Initiate failed\n"));
        return NOK;
    }

    /* Configure the WLAN hardware */
    Stt = whal_hwCtrl_ConfigHw (pWhalCtrl->pHwCtrl, (void *)whalCtrl_ReConfigCb, hWhalCtrl, TRUE);
    
    return OK;
}
/** 
 * \fn     wlanDrvIf_Xmit
 * \brief  Packets transmission
 * 
 * The network stack calls this function in order to transmit a packet
 *     through the WLAN interface.
 * The packet is inserted to the drver Tx queues and its handling is continued
 *     after switching to the driver context.
 *
 * \note   
 * \param  skb - The Linux packet buffer structure
 * \param  dev - The driver network-interface handle
 * \return 0 (= OK)
 * \sa     
 */ 
static int wlanDrvIf_Xmit (struct sk_buff *skb, struct net_device *dev)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
	TTxCtrlBlk *  pPktCtrlBlk;
	int status;

	CL_TRACE_START_L1();

	os_profile (drv, 0, 0);
	drv->stats.tx_packets++;
	drv->stats.tx_bytes += skb->len;

	/* Allocate a TxCtrlBlk for the Tx packet and save timestamp, length and packet handle */
	pPktCtrlBlk = TWD_txCtrlBlk_Alloc (drv->tCommon.hTWD);

	pPktCtrlBlk->tTxDescriptor.startTime    = os_timeStampMs(drv); /* remove use of skb->tstamp.off_usec */
	pPktCtrlBlk->tTxDescriptor.length       = skb->len;
	pPktCtrlBlk->tTxPktParams.pInputPkt     = skb;

	/* Point the first BDL buffer to the Ethernet header, and the second buffer to the rest of the packet */
	pPktCtrlBlk->tTxnStruct.aBuf[0] = skb->data;
	pPktCtrlBlk->tTxnStruct.aLen[0] = ETHERNET_HDR_LEN;
	pPktCtrlBlk->tTxnStruct.aBuf[1] = skb->data + ETHERNET_HDR_LEN;
	pPktCtrlBlk->tTxnStruct.aLen[1] = (TI_UINT16)skb->len - ETHERNET_HDR_LEN;
	pPktCtrlBlk->tTxnStruct.aLen[2] = 0;

	/* Send the packet to the driver for transmission. */
	status = txDataQ_InsertPacket (drv->tCommon.hTxDataQ, pPktCtrlBlk,(TI_UINT8)skb->priority);

	/* If failed (queue full or driver not running), drop the packet. */
    if (status != TI_OK)
    {
        drv->stats.tx_errors++;
    }
	os_profile (drv, 1, 0);

	CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "TX", "");

	return 0;
}
/***********************************************************************
 *                        idle_to_selfWait
 ***********************************************************************
DESCRIPTION:


INPUT:

OUTPUT:

RETURN:     TI_OK on success, TI_NOK otherwise

************************************************************************/
static TI_STATUS idle_to_selfWait (void *pData)
{
	conn_t    *pConn = (conn_t *)pData;
	TI_UINT16  randomTime;

	siteMgr_join (pConn->hSiteMgr);

	/* get a randomTime that is constructed of the lower 13 bits ot the system time to
	   get a MS random time of ~8000 ms */
	randomTime = os_timeStampMs (pConn->hOs) & 0x1FFF;

	/* Update current BSS connection type and mode */
	currBSS_updateConnectedState (pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT);

	tmr_StartTimer (pConn->hConnTimer,
	                conn_timeout,
	                (TI_HANDLE)pConn,
	                pConn->timeout + randomTime,
	                TI_FALSE);

	return TI_OK;
}
/*
 *      Timer function that is called for every x time interval
 *   That will invoke a process if any down limit as occurred.
 *
 ************************************************************************/
static void TimerMonitor_TimeOut (TI_HANDLE hTrafficMonitor, TI_BOOL bTwdInitOccured)
{

	TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
	TrafficAlertElement_t *AlertElement;
	TI_UINT32 CurentTime;
	TI_UINT32 activeTrafDownEventsNum = 0;
	TI_UINT32 trafficDownMinTimeout = 0xFFFFFFFF;

	if (TrafficMonitor == NULL)
		return;

	AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
	CurentTime = os_timeStampMs(TrafficMonitor->hOs);


	/* go over all the Down elements and check for alert */
	while (AlertElement) {
		if (AlertElement->CurrentState != ALERT_WAIT_FOR_RESET) {
			if (AlertElement->Direction == TRAFF_DOWN) {
				isThresholdDown(AlertElement,CurentTime);
			}
		}

		if ((AlertElement->Direction == TRAFF_DOWN) && (AlertElement->Trigger == TRAFF_EDGE) && (AlertElement->CurrentState == ALERT_OFF) && (AlertElement->Enabled == TI_TRUE)) {
			/* Increase counter of active traffic down events */
			activeTrafDownEventsNum++;

			/* Search for the alert with the most short Interval time - will be used to start timer */
			if ((AlertElement->TimeIntervalMs) < (trafficDownMinTimeout))
				trafficDownMinTimeout = AlertElement->TimeIntervalMs;
		}

		AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
	}

	TrafficMonitor_ChangeDownTimerStatus (TrafficMonitor,activeTrafDownEventsNum,trafficDownMinTimeout);

}
Exemple #21
0
/**
 * \brief	Stop the timer guarding the waiting for a missing packet
 *
 *			Stops the timer ONLY for the specified TID - other TID's timers will
 *			still run (if started)
 *
 * \param	uTid	index of TID timer to stop
 */
static void StopMissingPktTimer(TRxQueue *pRxQueue, TI_UINT8 uTid)
{
	TI_UINT8 i;
	TI_UINT32 uMinRequestTime;
	TI_UINT8 uNextClient;
	TI_UINT32 uNowMs;
	TRxQueueTidDataBase *pTidInfo = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uTid]);

	/* mark this TID no longer needs the timer */
	pTidInfo->uMissingPktTimeStamp = 0xffffffff;

	/* if timer was not started for this TID, don't stop it */
	if ( pRxQueue->uMissingPktTimerClient != uTid ) {
		return;
	}

	uMinRequestTime = 0xffffffff;
	uNextClient = 0;
	uNowMs = os_timeStampMs(pRxQueue->hOs);

	/* stop timer */
	tmr_StopTimer(pRxQueue->hMissingPktTimer);
	pRxQueue->uMissingPktTimerClient = TID_CLIENT_NONE;

	/* find the minimum request time */
	for (i = 0; i < MAX_NUM_OF_802_1d_TAGS; i++) {
		if (pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[i].uMissingPktTimeStamp < uMinRequestTime) {
			uMinRequestTime = pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[i].uMissingPktTimeStamp;
			uNextClient = i;
		}
	}

	/* restart timer if any requests left */
	if (uMinRequestTime < 0xffffffff) {
		tmr_StartTimer (pRxQueue->hMissingPktTimer, MissingPktTimeout, pRxQueue, uMinRequestTime + BA_SESSION_TIME_TO_SLEEP - uNowMs, TI_FALSE);
		pRxQueue->uMissingPktTimerClient = uNextClient;
	}
}
/**
 * Activates the next measurement request.
 * 
 * @param hMeasurementMgr A handle to the Measurement Manager module.
 * 
 * @date 16-Dec-2005
 */
TI_STATUS measurementMgr_activateNextRequest(TI_HANDLE hMeasurementMgr)
{
    measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr;
    requestHandler_t * pRequestH = (requestHandler_t *) pMeasurementMgr->hRequestH;
    MeasurementRequest_t * pRequestArr[MAX_NUM_REQ];
    TI_UINT8 numOfRequestsInParallel = 0;
    TI_BOOL valid;
    TI_UINT8 index;

	/* Keep note of the time we started processing the request. this will be used */
    /* to give the measurementSRV a time frame to perform the measurement operation */
    pMeasurementMgr->currentRequestStartTime = os_timeStampMs(pMeasurementMgr->hOs);

    do
    {
        TI_STATUS status;

        pRequestH->activeRequestID += numOfRequestsInParallel;
        pRequestH->numOfWaitingRequests -= numOfRequestsInParallel;

        for (index = 0; index < MAX_NUM_REQ; index++)
        {
            pRequestArr[index] = NULL;
        }
        numOfRequestsInParallel = 0;

        /* Getting the next request/requests from the request handler */
        status = requestHandler_getNextReq(pMeasurementMgr->hRequestH, TI_FALSE, pRequestArr, 
                                           &numOfRequestsInParallel);
        
        /* Checking if there are no waiting requests */
        if (status != TI_OK)
        {
            return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr);
        }

        /* Checking validity of request/s */
        valid = measurementMgr_isRequestValid(pMeasurementMgr, pRequestArr, 
                                numOfRequestsInParallel);

        /* Checking if the current request is Beacon Table */
        if( (numOfRequestsInParallel == 1) && 
            (pRequestArr[0]->Type == MSR_TYPE_BEACON_MEASUREMENT) &&
            (pRequestArr[0]->ScanMode == MSR_SCAN_MODE_BEACON_TABLE) )
        {
            pMeasurementMgr->buildReport(hMeasurementMgr, *(pRequestArr[0]), NULL);
            valid = TI_FALSE; /* In order to get the next request/s*/
        }
        
    } while (valid == TI_FALSE);
    

    /* Ignore requests if traffic intensity is high */
    if (measurementMgr_isTrafficIntensityHigherThanThreshold(pMeasurementMgr) == TI_TRUE)
    {
        measurementMgr_rejectPendingRequests(pMeasurementMgr, MSR_REJECT_TRAFFIC_INTENSITY_TOO_HIGH);

        return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
                               MEASUREMENTMGR_EVENT_SEND_REPORT, pMeasurementMgr);
    }
    
    pMeasurementMgr->measuredChannelID = pRequestArr[0]->channelNumber;
  
    /* Request resource from the SCR */
    return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), 
        MEASUREMENTMGR_EVENT_REQUEST_SCR, pMeasurementMgr);    
}   
/**
 * \\n
 * \date 08-November-2005\n
 * \brief Handle a START_SUCCESS event by starting different measure types and setting timers.\n
 *
 * Function Scope \e Public.\n
 * \param hMeasurementSrv - handle to the Measurement SRV object.\n
 * \return always TI_OK.\n
 */
TI_STATUS measurementSRVSM_startMeasureTypes( TI_HANDLE hMeasurementSRV )
{
	measurementSRV_t      *pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV;
	TI_UINT8                 requestIndex, rangeIndex;
	TI_INT8                  rangeUpperBound;
	TTwdParamInfo         tTwdParam;
	TI_STATUS             status;
	TNoiseHistogram       pNoiseHistParams;
	TApDiscoveryParams    pApDiscoveryParams;
	TI_UINT32                currentTime = os_timeStampMs( pMeasurementSRV->hOS );

	/* check if request time has expired (note: timer wrap-around is also handled)*/
	if ( (pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs)
	        < currentTime )
	{
		TI_INT32 i;

		TRACE2( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": request time has expired, request expiry time:%d, current time:%d\n", pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs, currentTime);

		/* mark that all measurement types has failed */
		for ( i = 0; i < pMeasurementSRV->msrRequest.numberOfTypes; i++ )
		{
			pMeasurementSRV->msrReply.msrTypes[ i ].status = MSR_REJECT_MAX_DELAY_PASSED;
		}

		/* send a measurement complete event */
		measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState),
		                          MSR_SRV_EVENT_ALL_TYPES_COMPLETE );

		return TI_OK;
	}

	/* Going over all request types that should be executed in parallel
	to start their timers and execute the measurement */
	for ( requestIndex = 0; requestIndex < pMeasurementSRV->msrRequest.numberOfTypes ; requestIndex++ )
	{
		switch (pMeasurementSRV->msrRequest.msrTypes[ requestIndex ].msrType)
		{
		case MSR_TYPE_CCA_LOAD_MEASUREMENT:
			/* Clearing the Medium Occupancy Register */
			tTwdParam.paramType = TWD_MEDIUM_OCCUPANCY_PARAM_ID;
			tTwdParam.content.interogateCmdCBParams.fCb = (void *)MacServices_measurementSRV_dummyChannelLoadParamCB;
			tTwdParam.content.interogateCmdCBParams.hCb = hMeasurementSRV;
			tTwdParam.content.interogateCmdCBParams.pCb =
			    (TI_UINT8*)&pMeasurementSRV->mediumOccupancyResults;
			status = cmdBld_GetParam (pMeasurementSRV->hCmdBld, &tTwdParam);
			if ( TI_OK == status  )
			{
				TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Medium Usage has been nullified, starting timer.\n");

				/* Start Timer */
				tmr_StartTimer (pMeasurementSRV->hRequestTimer[requestIndex],
				                MacServices_measurementSRV_requestTimerExpired,
				                (TI_HANDLE)pMeasurementSRV,
				                pMeasurementSRV->msrRequest.msrTypes[requestIndex].duration,
				                TI_FALSE);
				pMeasurementSRV->bRequestTimerRunning[requestIndex] = TI_TRUE;
			}
			else
			{
				TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": TWD_GetParam (for channel load) returned status %d\n", status);
			}

			break;

		case MSR_TYPE_NOISE_HISTOGRAM_MEASUREMENT:
			/* Set Noise Histogram Cmd Params */
			pNoiseHistParams.cmd = START_NOISE_HIST;
			pNoiseHistParams.sampleInterval = DEF_SAMPLE_INTERVAL;
			os_memoryZero( pMeasurementSRV->hOS, &(pNoiseHistParams.ranges[0]), MEASUREMENT_NOISE_HISTOGRAM_NUM_OF_RANGES );

			/* Set Ranges */
			/* (-87) - First Range's Upper Bound */
			rangeUpperBound = -87;

			/* Previously we converted from RxLevel to dBm - now this isn't necessary */
			/* rangeUpperBound = TWD_convertRSSIToRxLevel( pMeasurementSRV->hTWD, -87); */

			for (rangeIndex = 0; rangeIndex < MEASUREMENT_NOISE_HISTOGRAM_NUM_OF_RANGES -1; rangeIndex++)
			{
				if (rangeUpperBound > 0)
				{
					pNoiseHistParams.ranges[rangeIndex] = 0;
				}
				else
				{
					pNoiseHistParams.ranges[rangeIndex] = rangeUpperBound;
				}
				rangeUpperBound += 5;
			}
			pNoiseHistParams.ranges[rangeIndex] = 0xFE;

			/* Print for Debug */
			TRACE8(pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ":Noise histogram Measurement Ranges:\n%d %d %d %d %d %d %d %d\n", (TI_INT8) pNoiseHistParams.ranges[0], (TI_INT8) pNoiseHistParams.ranges[1], (TI_INT8) pNoiseHistParams.ranges[2], (TI_INT8) pNoiseHistParams.ranges[3], (TI_INT8) pNoiseHistParams.ranges[4], (TI_INT8) pNoiseHistParams.ranges[5], (TI_INT8) pNoiseHistParams.ranges[6], (TI_INT8) pNoiseHistParams.ranges[7]);

			/* Send a Start command to the FW */
			status = cmdBld_CmdNoiseHistogram (pMeasurementSRV->hCmdBld, &pNoiseHistParams, NULL, NULL);

			if ( TI_OK == status )
			{
				/* Print for Debug */
				TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Sent noise histogram command. Starting timer\n");

				/* Start Timer */
				tmr_StartTimer (pMeasurementSRV->hRequestTimer[requestIndex],
				                MacServices_measurementSRV_requestTimerExpired,
				                (TI_HANDLE)pMeasurementSRV,
				                pMeasurementSRV->msrRequest.msrTypes[requestIndex].duration,
				                TI_FALSE);
				pMeasurementSRV->bRequestTimerRunning[requestIndex] = TI_TRUE;
			}
			else
			{
				TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": TWD_NoiseHistogramCmd returned status %d\n", status);
			}
			break;

		case MSR_TYPE_BEACON_MEASUREMENT:
			/* set all parameters in the AP discovery command */
			pApDiscoveryParams.scanDuration = pMeasurementSRV->msrRequest.msrTypes[ requestIndex ].duration * 1000;
			pApDiscoveryParams.numOfProbRqst = 1;
			pApDiscoveryParams.txdRateSet = HW_BIT_RATE_1MBPS;
			pApDiscoveryParams.ConfigOptions = RX_CONFIG_OPTION_FOR_MEASUREMENT;
			pApDiscoveryParams.FilterOptions = RX_FILTER_OPTION_DEF_PRSP_BCN;
			pApDiscoveryParams.txPowerDbm = pMeasurementSRV->msrRequest.txPowerDbm;
			pApDiscoveryParams.scanOptions = SCAN_ACTIVE; /* both scan type and band are 0 for active and */
			/* 2.4 GHz, respectively, but 2.4 is not defined */

			/* band determined at the initiate measurement command not at that structure */

			/* scan mode go into the scan option field */
			if ( MSR_SCAN_MODE_PASSIVE == pMeasurementSRV->msrRequest.msrTypes[ requestIndex ].scanMode )
			{
				pApDiscoveryParams.scanOptions |= SCAN_PASSIVE;
			}

			/* Send AP Discovery command */
			status = cmdBld_CmdApDiscovery (pMeasurementSRV->hCmdBld, &pApDiscoveryParams, NULL, NULL);

			if ( TI_OK == status )
			{
				TRACE7( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": AP discovery command sent. Params:\n scanDuration=%d, scanOptions=%d, numOfProbRqst=%d, txdRateSet=%d, txPowerDbm=%d, configOptions=%d, filterOptions=%d\n Starting timer...\n", pApDiscoveryParams.scanDuration, pApDiscoveryParams.scanOptions, pApDiscoveryParams.numOfProbRqst, pApDiscoveryParams.txdRateSet, pApDiscoveryParams.txPowerDbm, pApDiscoveryParams.ConfigOptions, pApDiscoveryParams.FilterOptions);

				/* Start Timer */
				tmr_StartTimer (pMeasurementSRV->hRequestTimer[requestIndex],
				                MacServices_measurementSRV_requestTimerExpired,
				                (TI_HANDLE)pMeasurementSRV,
				                pMeasurementSRV->msrRequest.msrTypes[requestIndex].duration,
				                TI_FALSE);
				pMeasurementSRV->bRequestTimerRunning[ requestIndex ] = TI_TRUE;
			}
			else
			{
				TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": TWD_ApDiscoveryCmd returned status %d\n", status);
			}
			break;

		case MSR_TYPE_BASIC_MEASUREMENT: /* not supported in current implemntation */
		case MSR_TYPE_FRAME_MEASUREMENT: /* not supported in current implemntation */
		default:
			TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": Measurement type %d is not supported\n", pMeasurementSRV->msrRequest.msrTypes[ requestIndex ].msrType);
			break;
		}
	}

	/* if no measurement types are running, sen al types complete event.
	   This can happen if all types failed to start */
	if ( TI_TRUE == measurementSRVIsMeasurementComplete( hMeasurementSRV ))
	{
		/* send the event */
		measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState),
		                          MSR_SRV_EVENT_ALL_TYPES_COMPLETE );
	}

	return TI_OK;
}
/**
 * \\n
 * \date 08-November-2005\n
 * \brief Handle a DRIVER_MODE_SUCCESS event by sending start measure command to the FW.\n
 *
 * Function Scope \e Public.\n
 * \param hMeasurementSrv - handle to the Measurement SRV object.\n
 * \return always TI_OK.\n
 */
TI_STATUS measurementSRVSM_requestMeasureStart( TI_HANDLE hMeasurementSRV )
{
	measurementSRV_t     *pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV;
	TMeasurementParams    pMeasurementCmd;
	TI_STATUS             status;
	TI_UINT32                currentTime = os_timeStampMs( pMeasurementSRV->hOS );

	/* check if request time has expired (note: timer wrap-around is also handled)*/
	if ( (pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs)
	        < currentTime )
	{
		TI_INT32 i;

		TRACE2( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": request time has expired, request expiry time:%d, current time:%d\n", pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs, currentTime);

		/* mark that all measurement types has failed */
		for ( i = 0; i < pMeasurementSRV->msrRequest.numberOfTypes; i++ )
		{
			pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_NOK;
		}

		/* send a measurement complete event */
		measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState),
		                          MSR_SRV_EVENT_STOP_COMPLETE );

		return TI_OK;
	}

	pMeasurementCmd.channel = pMeasurementSRV->msrRequest.channel;
	pMeasurementCmd.band = pMeasurementSRV->msrRequest.band;
	pMeasurementCmd.duration = 0; /* Infinite */
	pMeasurementCmd.eTag = pMeasurementSRV->msrRequest.eTag;

	if ( measurementSRVIsBeaconMeasureIncluded( hMeasurementSRV ))
	{  /* Beacon Measurement is one of the types */

		/* get the current channel */
		TTwdParamInfo	paramInfo;

		paramInfo.paramType = TWD_CURRENT_CHANNEL_PARAM_ID;
		cmdBld_GetParam (pMeasurementSRV->hCmdBld, &paramInfo);

		pMeasurementCmd.ConfigOptions = RX_CONFIG_OPTION_FOR_MEASUREMENT;

		/* check if the request is on the serving channel */
		if ( paramInfo.content.halCtrlCurrentChannel == pMeasurementSRV->msrRequest.channel )
		{
			/* Set the RX Filter to the join one, so that any packets will
			be received on the serving channel - beacons and probe requests for
			the measurmenet, and also data (for normal operation) */
			pMeasurementCmd.FilterOptions = RX_FILTER_OPTION_JOIN;
		}
		else
		{
			/* not on the serving channle - only beacons and rpobe responses are required */
			pMeasurementCmd.FilterOptions = RX_FILTER_OPTION_DEF_PRSP_BCN;
		}
	}
	else
	{  /* No beacon measurement - use the current RX Filter */
		pMeasurementCmd.ConfigOptions = 0xffffffff;
		pMeasurementCmd.FilterOptions = 0xffffffff;
	}

	/* Send start measurement command */
	status = cmdBld_CmdMeasurement (pMeasurementSRV->hCmdBld,
	                                &pMeasurementCmd,
	                                (void *)measurementSRVSM_requestMeasureStartResponseCB,
	                                pMeasurementSRV);

	if ( TI_OK != status )
	{
		TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": Failed to send measurement start command, statud=%d,\n", status);

		/* keep the faulty return status */
		pMeasurementSRV->returnStatus = status;

		/* send a measurement start fail event */
		return measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState),
		                                 MSR_SRV_EVENT_START_FAILURE );
	}

	TRACE6( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": measure start command sent. Params:\n channel=%d, band=%d, duration=%d, \n configOptions=0x%x, filterOptions=0x%x, status=%d, \n", pMeasurementCmd.channel, pMeasurementCmd.band, pMeasurementCmd.duration, pMeasurementCmd.ConfigOptions, pMeasurementCmd.FilterOptions, status);

	/* start the FW guard timer */
	pMeasurementSRV->bStartStopTimerRunning = TI_TRUE;
	tmr_StartTimer (pMeasurementSRV->hStartStopTimer,
	                MacServices_measurementSRV_startStopTimerExpired,
	                (TI_HANDLE)pMeasurementSRV,
	                MSR_FW_GUARD_TIME,
	                TI_FALSE);

	return TI_OK;
}
/***********************************************************************
 *                        calcCreditFromTimer
 ***********************************************************************
DESCRIPTION:    This function is called when credit calculation timer
				is expired. it calculate the credit for the admission ctrl
				credit algorithm


INPUT:	    hTxCtrl         - handle to the ts data object
            bTwdInitOccured - Indicates if TWDriver recovery occured since timer started 

OUTPUT:     None

RETURN:     void
************************************************************************/
static void calcCreditFromTimer(TI_HANDLE hTxCtrl, TI_BOOL bTwdInitOccured)
{
	OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS	mediumTimeCross;
	txCtrl_t	*pTxCtrl = (txCtrl_t *)hTxCtrl;
	TI_UINT32		ac;
	TI_INT32		prevCredit;
	TI_INT32		highCreditThreshold;
	TI_INT32		lowCreditThreshold;
	TI_INT32		usageRatio;
	TI_INT32		currUsage;
	TI_INT32		prevUsage;
	TI_UINT32		currentTimeStamp = os_timeStampMs(pTxCtrl->hOs);  /* get current time stamp */
	
	/* 
	 *  For each AC under admission control calculate the new usage and credit time,
	 *     and send events if a threshold is crossed. 
	 */
	for(ac = 0 ; ac < MAX_NUM_OF_AC ; ac++)
	{
		/* check if this queue is under admission ctrl operation */
		if(pTxCtrl->mediumTime[ac] == 0)
		{
TRACE1(pTxCtrl->hReport, REPORT_SEVERITY_INFORMATION, ": ac = %d mediumTime = 0 \n", ac);
			
			continue;
		}

		/* in case of wraparound */
		if(currentTimeStamp < pTxCtrl->lastCreditCalcTimeStamp[ac])
			pTxCtrl->lastCreditCalcTimeStamp[ac] = 0;
		
		/* store prev credit */
		prevCredit = pTxCtrl->credit[ac];

		/* Calculate the medium usage ratio:    totalUsedTime / mediumTime * 1000
		   Note that since the totalUsedTime is in usec and not msec we don't multiply by 1000.	 */
		usageRatio = pTxCtrl->totalUsedTime[ac] / pTxCtrl->mediumTime[ac];

		/* calculate credit */
		pTxCtrl->credit[ac] += (currentTimeStamp - pTxCtrl->lastCreditCalcTimeStamp[ac]) - usageRatio;
		
		/* update last time stamp */
		pTxCtrl->lastCreditCalcTimeStamp[ac] = currentTimeStamp;

		/* in case credit is bigger than mediumTime -> set credit to medium time */
		if (pTxCtrl->credit[ac] > (TI_INT32)(pTxCtrl->mediumTime[ac]) )
			pTxCtrl->credit[ac] = pTxCtrl->mediumTime[ac];

       TRACE2(pTxCtrl->hReport, REPORT_SEVERITY_INFORMATION, "credit = %d  | TotalUsedTime = %d\n", pTxCtrl->credit[ac], pTxCtrl->totalUsedTime[ac]/1000);

		/* Check medium-usage threshold cross events */
		/*********************************************/
		/*
		 * The medium-usage events are defined as follows:
		 * The high threshold triggers event only when crossed upward (traffic increased above threshold).
		 * The low threshold triggers event only when crossed downward (traffic decreased below threshold).
		 * Thus, the two thresholds provide hysteresis and prevent multiple triggering.
		 * The high threshold should be greater than the low threshold. 
		 * 
		 *   Note:	The driver doesn't delay traffic even if violating the usage limit!
		 *			It only indicates the user application about the thresholds crossing.
		 */

		highCreditThreshold = (TI_INT32)((pTxCtrl->mediumTime[ac])*(pTxCtrl->highMediumUsageThreshold[ac])/100); 
		lowCreditThreshold  = (TI_INT32)((pTxCtrl->mediumTime[ac])*(pTxCtrl->lowMediumUsageThreshold[ac])/100);

		/* The credit is getting more negative as we get closer to the medium usage limit, so we invert
		     it before comparing to the thresholds (lower credit means higher usage). */
		currUsage = -pTxCtrl->credit[ac];
		prevUsage = -prevCredit;

		/* crossing below the low threshold */
		if ( (currUsage < lowCreditThreshold) && (prevUsage >= lowCreditThreshold) )
		{
			/* send event */
			mediumTimeCross.uAC = ac;
			mediumTimeCross.uHighOrLowThresholdFlag = (TI_UINT32)LOW_THRESHOLD_CROSS;
			mediumTimeCross.uAboveOrBelowFlag = (TI_UINT32)CROSS_BELOW;

			EvHandlerSendEvent(pTxCtrl->hEvHandler, IPC_EVENT_MEDIUM_TIME_CROSS, 
				(TI_UINT8 *)&mediumTimeCross, sizeof(OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS));

            TRACE3(pTxCtrl->hReport, REPORT_SEVERITY_INFORMATION, "crossed below low threshold !!! prevUsage = %d, currUsage = %d, lowCreditThreshold = %d\n",				prevUsage, currUsage, lowCreditThreshold);
		}
		
		/* crossing above the high threshold */
		else if ( (currUsage > highCreditThreshold) && (prevUsage <= highCreditThreshold) )
		{
			/* send event */
			mediumTimeCross.uAC = ac;
			mediumTimeCross.uHighOrLowThresholdFlag = (TI_UINT32)HIGH_THRESHOLD_CROSS;
			mediumTimeCross.uAboveOrBelowFlag = (TI_UINT32)CROSS_ABOVE;

			EvHandlerSendEvent(pTxCtrl->hEvHandler, IPC_EVENT_MEDIUM_TIME_CROSS, 
				(TI_UINT8 *)&mediumTimeCross, sizeof(OS_802_11_THRESHOLD_CROSS_INDICATION_PARAMS));

            TRACE3(pTxCtrl->hReport, REPORT_SEVERITY_INFORMATION, "crossed above high threshold !!! prevUsage = %d, currUsage = %d, highCreditThreshold = %d\n",				prevUsage, currUsage, highCreditThreshold);
		}

		/* reset totalUsedTime */
		pTxCtrl->totalUsedTime[ac] = 0;
	}
}
/**
 * Called when the SM is in an idle state and we receive a new measurement frame.
 *
 * @date 05-Jan-2006
 */
static TI_STATUS measurementMgrSM_acFrameReceived_fromIdle(void * pData)
{
	measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) pData;
	TI_UINT16 activationDelay;
	TI_STATUS status;
	paramInfo_t param;
	TI_UINT16 tbtt;

	/* handle frame request only if we're connected and measurement is enabled */
	if (pMeasurementMgr->Connected == TI_FALSE ||
	    pMeasurementMgr->Enabled == TI_FALSE) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Frame received while SM is in disconnected/disabled state\n");

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_ABORT, pMeasurementMgr);
	}

	/* Setting the frame Type */
	pMeasurementMgr->currentFrameType = pMeasurementMgr->newFrameRequest.frameType;

	TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Frame Type = %d\n", pMeasurementMgr->currentFrameType);

	/* Getting the Beacon Interval from the Site Mgr */
	param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM;
	status = siteMgr_getParam(pMeasurementMgr->hSiteMgr, &param);
	if (status != TI_OK) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Failed to retrieve beacon interval - not connected?\n");

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_ABORT, pMeasurementMgr);
	}

	/* converting beacon interval to msec */
	tbtt = (param.content.beaconInterval * 1024) / 1000;	/* from TU to msec */

	/* Initializing Activation Delay Time */
	activationDelay	= pMeasurementMgr->newFrameRequest.hdr->activatioDelay;
	activationDelay	*= tbtt;
	/* Adding the Measurement Offset to the activation delay */
	activationDelay	+= pMeasurementMgr->newFrameRequest.hdr->measurementOffset;

	/* Inserting all received measurement requests into the queue */
	status = requestHandler_insertRequests(pMeasurementMgr->hRequestH,
	                                       pMeasurementMgr->Mode,
	                                       pMeasurementMgr->newFrameRequest);

	/* Clean New Frame Params */
	os_memoryZero(pMeasurementMgr->hOs, &pMeasurementMgr->newFrameRequest,
	              sizeof(TMeasurementFrameRequest));

	if (status != TI_OK) {
		pMeasurementMgr->currentFrameType = MSR_FRAME_TYPE_NO_ACTIVE;

		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Could not insert request into the queue\n");

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_ABORT, pMeasurementMgr);
	}

	TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": New frame has been inserted into the queue\n");

	/* If frame type isn't Unicast add to Activation Delay a random delay */
	if ((pMeasurementMgr->currentFrameType != MSR_FRAME_TYPE_UNICAST) && (activationDelay > 0)) {
		activationDelay	+= ((os_timeStampMs(pMeasurementMgr->hOs) % MSR_ACTIVATION_DELAY_RANDOM)
		                    + MSR_ACTIVATION_DELAY_OFFSET);
	}

	TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Activation Delay in ms = %d\n", activationDelay);

	if (activationDelay > 0) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Going to wait for activation delay timer callback\n");

		/* Starting the Activation Delay Timer */
		tmr_StartTimer (pMeasurementMgr->hActivationDelayTimer,
		                measurementMgrSM_uponActivationDelayTimeout,
		                (TI_HANDLE)pMeasurementMgr,
		                activationDelay,
		                TI_FALSE);

		return TI_OK;
	} else {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Activating the next request immediately without waiting for callback\n");

		/* Calling to schedule the first waiting request */
		return measurementMgr_activateNextRequest(pData);
	}
}
/**
 * Called when the SCR callbacks with a RUN response or if the SCR
 * returned a RUN response when we requested it.
 *
 * @date 05-Jan-2006
 */
static TI_STATUS measurementMgrSM_acStartMeasurement(void * pData)
{
	measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) pData;

	/* Cryptic: the first struct is the requestHandler request while */
	/* the second one is the measurementSRV request */
	MeasurementRequest_t * pRequestArr[MAX_NUM_REQ];
	TMeasurementRequest request;

	paramInfo_t	*pParam;
	TI_UINT8 numOfRequestsInParallel;
	TI_UINT8 requestIndex;
	TI_UINT32 timePassed;
	TI_BOOL requestedBeaconMeasurement= TI_FALSE;
	TI_STATUS status;

	TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Starting Measurement operation\n");

	pParam = (paramInfo_t *)os_memoryAlloc(pMeasurementMgr->hOs, sizeof(paramInfo_t));
	if (!pParam) {
		return TI_NOK;
	}

	request.channel = pMeasurementMgr->measuredChannelID;
	request.startTime = 0;	/* ignored by MeasurementSRV for now - for .11k */
	request.numberOfTypes = 0;

	TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measured Channel = %d\n", pMeasurementMgr->measuredChannelID);

	pParam->paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
	pParam->content.channelCapabilityReq.channelNum = pMeasurementMgr->measuredChannelID;
	pParam->content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;

	if (pMeasurementMgr->measuredChannelID <= MAX_CHANNEL_IN_BAND_2_4) {
		request.band = RADIO_BAND_2_4_GHZ;
		pParam->content.channelCapabilityReq.band = RADIO_BAND_2_4_GHZ;
	} else {
		request.band = RADIO_BAND_5_0_GHZ;
		pParam->content.channelCapabilityReq.band = RADIO_BAND_5_0_GHZ;
	}

	regulatoryDomain_getParam(pMeasurementMgr->hRegulatoryDomain, pParam);

	request.txPowerDbm = pParam->content.channelCapabilityRet.maxTxPowerDbm;

	request.eTag = SCAN_RESULT_TAG_MEASUREMENT;
	os_memoryFree(pMeasurementMgr->hOs, pParam, sizeof(paramInfo_t));

	TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Querying Request Handler for the next request in the queue\n");

	/* Getting the next request/requests from the request handler */
	status = requestHandler_getNextReq(pMeasurementMgr->hRequestH, TI_TRUE, pRequestArr,
	                                   &numOfRequestsInParallel);

	if (status != TI_OK) {
		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Failed getting next request from Request Handler\n");

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_COMPLETE, pMeasurementMgr);
	}

	/* Save the number of requests in parallel so that once the */
	/* measurement operation ends we can get rid of this amount of requests */
	/* from the requestHandler */
	pMeasurementMgr->currentNumOfRequestsInParallel = numOfRequestsInParallel;

	for (requestIndex = 0; requestIndex < numOfRequestsInParallel; requestIndex++) {
		if (pRequestArr[requestIndex]->Type == MSR_TYPE_BEACON_MEASUREMENT) {
			requestedBeaconMeasurement = TI_TRUE;

			if (pRequestArr[requestIndex]->ScanMode == MSR_SCAN_MODE_BEACON_TABLE) {
				TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Beacon Table request encountered, building report now\n");

				/* building Report for beacon table request */
				pMeasurementMgr->buildReport(pMeasurementMgr, *pRequestArr[requestIndex], NULL);

				continue;
			}
		}

		/* save the request so we can reference it when results arrive */
		pMeasurementMgr->currentRequest[request.numberOfTypes] = pRequestArr[requestIndex];

		/* add the measurement type to the request's list */
		request.msrTypes[request.numberOfTypes].duration = pRequestArr[requestIndex]->DurationTime;
		request.msrTypes[request.numberOfTypes].scanMode = pRequestArr[requestIndex]->ScanMode;
		request.msrTypes[request.numberOfTypes].msrType = pRequestArr[requestIndex]->Type;

		TRACE3(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ":\n\nMeasurement Request #%d Details: Type = %d, Duration = %d\n\n",						request.numberOfTypes+1,						request.msrTypes[request.numberOfTypes].msrType,						request.msrTypes[request.numberOfTypes].duration);

		request.numberOfTypes++;
	}

	if (requestedBeaconMeasurement == TI_TRUE) {
		/* build a probe request template and send it to the HAL */
		TSetTemplate templateStruct;
		probeReqTemplate_t probeReqTemplate;
		TSsid broadcastSSID;

		templateStruct.ptr = (TI_UINT8 *) &probeReqTemplate;
		templateStruct.type = PROBE_REQUEST_TEMPLATE;
		templateStruct.eBand = request.band;
		templateStruct.uRateMask = RATE_MASK_UNSPECIFIED;
		broadcastSSID.len = 0;

		TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Sending probe request template...\n");

		buildProbeReqTemplate( pMeasurementMgr->hSiteMgr, &templateStruct, &broadcastSSID, request.band );
#ifdef XCC_MODULE_INCLUDED
		{	/* Insert Radio Mngt Capability IE according XCC4*/
			TI_UINT32				len = 0;
			measurementMgr_radioMngtCapabilityBuild (pMeasurementMgr,
			        templateStruct.ptr + templateStruct.len,
			        (TI_UINT8*)&len);
			templateStruct.len += len;
		}
#endif

		TWD_CmdTemplate (pMeasurementMgr->hTWD, &templateStruct, NULL, NULL);
	}

	/* Check if the maximum time to wait for the measurement request to */
	/* finish has already passed */
	timePassed = os_timeStampMs(pMeasurementMgr->hOs) - pMeasurementMgr->currentRequestStartTime;
	if (timePassed > MSR_START_MAX_DELAY) {
		TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Maximum delay to perform measurement operation has passed (%d / %d)\n",						MSR_START_MAX_DELAY, (os_timeStampMs(pMeasurementMgr->hOs) - pMeasurementMgr->currentRequestStartTime));

		pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequestsInParallel, MSR_REJECT_MAX_DELAY_PASSED);

		return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState),
		                              MEASUREMENTMGR_EVENT_COMPLETE, pMeasurementMgr);
	}

	/* Yalla, start measuring */
	TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Finished preparing request. Handing over to MeasurementSRV...\n");

	TWD_StartMeasurement (pMeasurementMgr->hTWD,
	                      &request,
	                      MSR_START_MAX_DELAY - timePassed,
	                      NULL, NULL,
	                      measurementMgr_MeasurementCompleteCB,
	                      pMeasurementMgr);

	return TI_OK;
}
/**
*
* roamingMngr_smHandover 
*
* \b Description: 
*
* This procedure is called when handover should be invoked.
*   Go over the candidate APs and start handover to each of them. 
 * If there's no candidate APs, disconnect.
 * Handover to the current AP is allowed only if the trigger is
 * low quality.
 * 
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smHandover(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t           *pRoamingMngr;
    bssEntry_t              *pApToConnect;
    apConn_connRequest_t    requestToApConn;

    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;

    if ((pRoamingMngr->handoverWasPerformed) && (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX))
    {   /* Handover with the current AP already failed, Disconnect */
        roamingMngr_smEvent(ROAMING_EVENT_FAILURE, pRoamingMngr);
        return;
    }
    if (pRoamingMngr->listOfCandidateAps.numOfNeighborBSS > 0)
    {   /* Neighbor APs are the highest priority to Roam */
        pRoamingMngr->candidateApIndex = 
            pRoamingMngr->listOfCandidateAps.neighborBSSList[pRoamingMngr->listOfCandidateAps.numOfNeighborBSS-1];
        pRoamingMngr->listOfCandidateAps.numOfNeighborBSS--;
    }
    else if (pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS > 0)
    {   /* Pre-Auth APs are the second priority to Roam */
        pRoamingMngr->candidateApIndex = 
            pRoamingMngr->listOfCandidateAps.preAuthBSSList[pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS-1];
        pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS--;
    }
    else if (pRoamingMngr->listOfCandidateAps.numOfRegularBSS > 0)
    {   /* Regular APs are APs that are not pre-authenticated and not Neighbor */
        pRoamingMngr->candidateApIndex = 
            pRoamingMngr->listOfCandidateAps.regularBSSList[pRoamingMngr->listOfCandidateAps.numOfRegularBSS-1];
        pRoamingMngr->listOfCandidateAps.numOfRegularBSS--;
    }
    else
    {   /* No Candidate APs */
        pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
    }

    TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smHandover, candidateApIndex=%d \n", pRoamingMngr->candidateApIndex);


    if (pRoamingMngr->candidateApIndex == INVALID_CANDIDATE_INDEX)
    {   /* No cnadidate to Roam to, only the current AP is candidate */
        if (pRoamingMngr->roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP)
        {   /* If the trigger to Roam is low quality, and there are no candidate APs
                to roam to, retain connected to the current AP */
            requestToApConn.requestType = (pRoamingMngr->handoverWasPerformed) ? AP_CONNECT_RECONNECT_CURR_AP : AP_CONNECT_RETAIN_CURR_AP;
            pRoamingMngr->candidateApIndex = CURRENT_AP_INDEX;
        }
        else
        {   /* Disconnect the BSS, there are no more APs to roam to */
            roamingMngr_smEvent(ROAMING_EVENT_FAILURE, pRoamingMngr);
            return;
        }
    }
    else
    {   /* There is a valid candidate AP */
        if (pRoamingMngr->roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
        {   /* Full re-connection should be perfromed */
            requestToApConn.requestType = AP_CONNECT_FULL_TO_AP; 
        }
        else
        {   /* Fast re-connection should be perfromed */
            requestToApConn.requestType = AP_CONNECT_FAST_TO_AP; 
        }
    }
#ifdef TI_DBG
    /* For debug */
    if (!pRoamingMngr->handoverWasPerformed)
    {   /* Take the time before the first handover started */
        pRoamingMngr->roamingHandoverStartedTimestamp = os_timeStampMs(pRoamingMngr->hOs);
    }
#endif
    
    if (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX)
    {   /* get the current AP */
        pApToConnect = apConn_getBSSParams(pRoamingMngr->hAPConnection);
        if (pApToConnect == NULL)
         return;
    }
    else
    {   /* get the candidate AP */
        pRoamingMngr->handoverWasPerformed = TI_TRUE;
        pApToConnect = &pRoamingMngr->pListOfAPs->BSSList[pRoamingMngr->candidateApIndex];
    }
    TRACE3(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smHandover, candidateApIndex=%d, requestType = %d, channel=%d \n", 							 pRoamingMngr->candidateApIndex, requestToApConn.requestType, pApToConnect->channel);

    requestToApConn.dataBufLength = 0;

    apConn_connectToAP(pRoamingMngr->hAPConnection, pApToConnect, &requestToApConn, TI_TRUE);
}
Exemple #29
0
/***********************************************************************
 *                        healthMonitor_proccessFailureEvent
 ***********************************************************************
DESCRIPTION:    this is the central error function - will be passed as call back 
                to the TnetWDriver modules. it will parse the error and dispatch the 
                relevant action (recovery or not) 

INPUT:      hHealthMonitor - health monitor handle
            bTwdInitOccured -   Indicates if TWDriver recovery occured since timer started 

OUTPUT:

RETURN:    

************************************************************************/
void healthMonitor_proccessFailureEvent (TI_HANDLE hHealthMonitor, TI_BOOL bTwdInitOccured)
{
    THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor;

    /* Check failure event validity */
    if (pHealthMonitor->failureEvent < MAX_FAILURE_EVENTS)
    {
        pHealthMonitor->recoveryTriggersNumber[pHealthMonitor->failureEvent] ++;

        TRACE2(pHealthMonitor->hReport, REPORT_SEVERITY_CONSOLE, "***** recovery trigger: failureEvent =%d *****, ts=%d\n", pHealthMonitor->failureEvent, os_timeStampMs(pHealthMonitor->hOs));
        WLAN_OS_REPORT (("***** recovery trigger: %s *****, ts=%d\n", sRecoveryTriggersNames[pHealthMonitor->failureEvent], os_timeStampMs(pHealthMonitor->hOs)));

        if (TWD_RecoveryEnabled (pHealthMonitor->hTWD))
        {
            pHealthMonitor->numOfRecoveryPerformed ++;
            drvMain_Recovery (pHealthMonitor->hDrvMain);
        }
        else
        {
            TRACE0(pHealthMonitor->hReport, REPORT_SEVERITY_CONSOLE, "healthMonitor_proccessFailureEvent: Recovery is disabled in tiwlan.ini, abort recovery process\n");
            WLAN_OS_REPORT(("healthMonitor_proccessFailureEvent: Recovery is disabled in tiwlan.ini, abort recovery process\n"));
        }

        pHealthMonitor->failureEvent = (TI_UINT32)NO_FAILURE;
    }
    else
    {
        TRACE1(pHealthMonitor->hReport, REPORT_SEVERITY_ERROR , "unsupported failure event = %d\n", pHealthMonitor->failureEvent);
    }    
}
Exemple #30
0
/**
 * \fn     scanCncnApp_SetParam
 * \brief  Parses and executes a set param command
 *
 * Parses and executes a set param command (start/stop one-shot/periodic/OS scan)
 *
 * \param  hScanCncn - handle to the scan concentrator object
 * \param  pParam - the param to set
 * \return operation status (OK / NOK / PARAM_NOT_SUPPORTED)
 * \sa     scanCncnApp_GetParam
 */
TI_STATUS scanCncnApp_SetParam (TI_HANDLE hScanCncn, paramInfo_t *pParam)
{
	TScanCncn   *pScanCncn = (TScanCncn*)hScanCncn;
	TI_UINT32   uCurrentTimeStamp;


	switch (pParam->paramType) {
	case SCAN_CNCN_START_APP_SCAN:

		/* verify that scan is not currently running */
		if (pScanCncn->eCurrentRunningAppScanClient != SCAN_SCC_NO_CLIENT) {
			/* Scan was not started successfully, send a scan complete event to the user */
			return TI_NOK;
		}

		/* set one-shot scan as running app scan client */
		pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_APP_ONE_SHOT;

		/* Perform aging process before the scan */
		scanResultTable_PerformAging(pScanCncn->hScanResultTable);

		/* start the scan */
		if (SCAN_CRS_SCAN_RUNNING !=
		        scanCncn_Start1ShotScan (hScanCncn, SCAN_SCC_APP_ONE_SHOT, pParam->content.pScanParams)) {
			/* Scan was not started successfully, mark that no app scan is running */
			pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT;
			return TI_NOK;
		}
		break;

	case SCAN_CNCN_STOP_APP_SCAN:
		/* verify that scan is currently running */
		if (pScanCncn->eCurrentRunningAppScanClient != SCAN_SCC_NO_CLIENT) {
			scanCncn_StopScan (hScanCncn, SCAN_SCC_APP_ONE_SHOT);
		}
		break;

	case SCAN_CNCN_START_PERIODIC_SCAN:
		/* verify that scan is not currently running */
		if (SCAN_SCC_NO_CLIENT != pScanCncn->eCurrentRunningAppScanClient) {
			/* Scan was not started successfully, send a scan complete event to the user */
			return TI_NOK;
		}

		/* set one-shot scan as running app scan client */
		pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_APP_PERIODIC;

		/* Perform aging process before the scan */
		scanResultTable_PerformAging(pScanCncn->hScanResultTable);

		/* start the scan */
		if (SCAN_CRS_SCAN_RUNNING !=
		        scanCncn_StartPeriodicScan (hScanCncn, SCAN_SCC_APP_PERIODIC, pParam->content.pPeriodicScanParams)) {
			WLAN_OS_REPORT (("Scan was not started. Verify scan parametrs or SME mode\n"));

			/* Scan was not started successfully, mark that no app scan is running */
			pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT;
			return TI_NOK;
		}
		break;

	case SCAN_CNCN_STOP_PERIODIC_SCAN:
		/* verify that scan is currently running */
		if (pScanCncn->eCurrentRunningAppScanClient != SCAN_SCC_NO_CLIENT) {
			scanCncn_StopPeriodicScan (hScanCncn, SCAN_SCC_APP_PERIODIC);
		}
		break;

	case SCAN_CNCN_BSSID_LIST_SCAN_PARAM:
		/* check if OID scans are enabled in the registry */
		if (0 == pScanCncn->tInitParams.uMinimumDurationBetweenOsScans) {
			return TI_NOK;
		}

		/* check if the last OID scan didn't start at a shorter duration than the configured minimum */
		uCurrentTimeStamp = os_timeStampMs (pScanCncn->hOS);
		if ( (uCurrentTimeStamp - pScanCncn->uOSScanLastTimeStamp) <
		        (pScanCncn->tInitParams.uMinimumDurationBetweenOsScans * 1000) ) { /*converted to ms */
			return TI_NOK;
		}

		/* check that no other scan is currently running */
		if (SCAN_SCC_NO_CLIENT != pScanCncn->eCurrentRunningAppScanClient) {
			return TI_NOK;
		}

		/* set one-shot scan as running app scan client */
		pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_APP_ONE_SHOT;

		/* mark that an OID scan process has started */
		pScanCncn->bOSScanRunning = TI_TRUE;
		pScanCncn->uOSScanLastTimeStamp = uCurrentTimeStamp;

		if (0 != pParam->content.pScanParams->desiredSsid.len) {
			pScanCncn->tOsScanParams.desiredSsid.len = pParam->content.pScanParams->desiredSsid.len;
			os_memoryCopy(pScanCncn->hOS, pScanCncn->tOsScanParams.desiredSsid.str, pParam->content.pScanParams->desiredSsid.str, pParam->content.pScanParams->desiredSsid.len);
		} else {
			pScanCncn->tOsScanParams.desiredSsid.len = 0;
			pScanCncn->tOsScanParams.desiredSsid.str[ 0 ] = '\0'; /* broadcast scan */
		}

		pScanCncn->tOsScanParams.scanType = pParam->content.pScanParams->scanType;

		/* Perform aging process before the scan */
		scanResultTable_PerformAging(pScanCncn->hScanResultTable);

		/* and actually start the scan */
		genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_START_SCAN, hScanCncn);

		break;

	case SCAN_CNCN_SET_SRA:
		scanResultTable_SetSraThreshold(pScanCncn->hScanResultTable, pParam->content.uSraThreshold);
		break;

	case SCAN_CNCN_SET_RSSI:
		pScanCncn->tInitParams.nRssiThreshold = pParam->content.nRssiThreshold;
		break;

	default:
		return PARAM_NOT_SUPPORTED;
	}

	return TI_OK;
}