Example #1
0
int
timerLoop (void)
{
    IxOsalTimeval now;
    IxOsalVoidFnVoidPtr callback = NULL;
    void *callbackParam = NULL;
    IxOsalTimerRec *nextTimer;
    IX_STATUS status;

    while (1)
    {
        /*
         *  This loop catches all cases in a simple way.  If multiple
         *  timers expire together, then lowest will be <=0 until all
         *  have been processed and the queue get won't get invoked.
         */

        status =
            ixOsalSemaphoreWait (&ixOsalCriticalSectSem,
            IX_OSAL_WAIT_FOREVER);
        if (status != IX_SUCCESS)
        {
            ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
                "timerLoop  fail to get semaphore \n", 0, 0, 0, 0, 0, 0);
            return IX_FAIL;
        }

        ixOsalTimeGet (&now);
        nextTimer = findNextTimeout (now);

        if ((nextTimer == NULL)
            || IX_OSAL_TIME_GT ((nextTimer->expires), (now)))
        {
            callback = NULL;
        }
        else
        {
            rescheduleTimer (nextTimer);
            callback = nextTimer->callback;
            callbackParam = nextTimer->callbackParam;
        }

        status = ixOsalSemaphorePost (&ixOsalCriticalSectSem);
        if (status != IX_SUCCESS)
        {
            ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
                "timerLoop  fail to release semaphore \n", 0, 0, 0, 0, 0, 0);
            return IX_FAIL;
        }

        if (callback != NULL)
        {
            callTimerCallback (callback, callbackParam);
        }
        else
        {
            timerSleep (nextTimer, now);
        }
    }
}
Example #2
0
PRIVATE
IX_STATUS
ixHssAccCodeletChanThreadMain (
    void* arg,
    void** ptrRetObj)
{
    ClientInfo *pClientInfo = (ClientInfo *)arg;
    Message *pMessage;

    while (1)
    {
        (void) ixOsalSemaphoreWait (
            &pClientInfo->messageSem, IX_OSAL_WAIT_FOREVER);

        pMessage = &pClientInfo->messageQ[pClientInfo->qTail++];
        pClientInfo->qTail %= NUMELEMS(pClientInfo->messageQ);

        switch (pMessage->type)
        {
        case RxCallback:
            ixHssAccCodeletChanRxCallbackProcess (
                pClientInfo->hssPortId,
                pMessage->params.rxOffset,
                pMessage->params.txOffset,
                pMessage->params.numHssErrs);
            break;
        }
    } /* while (1) */

    return IX_SUCCESS;
}
Example #3
0
PRIVATE void
timerSleep (IxOsalTimerRec * nextTimer, IxOsalTimeval now)
{
    UINT32 ticks;
    IxOsalTimeval temp;

    if (nextTimer == NULL)
    {
        ticks = IX_OSAL_WAIT_FOREVER;
    }
    else
    {
        temp.secs = nextTimer->expires.secs;
        temp.nsecs = nextTimer->expires.nsecs;

        IX_OSAL_TIME_SUB (temp, now);

        ticks = IX_OSAL_TIMEVAL_TO_TICKS (temp);

        /*
         * We should sleep but the period is less than a tick
         * * away, rounding up. 
         */
        if (ticks == 0)
        {
            ticks = 1;
        }
    }

    /*
     * Note: Status is ignored here, wait intentionally 
     */
    ixOsalSemaphoreWait (&ixOsalTimerRecalcSem, ticks);

}
Example #4
0
PUBLIC IX_STATUS
ixOsalTimerCancel (IxOsalTimer * timer)
{
    UINT32 id;
    UINT32 i;
    IX_STATUS status = IX_FAIL;

    if (ixOsalTimerInited == FALSE)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "ixOsalTimerCancel: call schedule APIs first to start timer \n",
            0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    id = *timer;

    status =
        ixOsalSemaphoreWait (&ixOsalCriticalSectSem, IX_OSAL_WAIT_FOREVER);

    if (status != IX_SUCCESS)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "ixOsalTimerCancel: fail to get semaphore \n", 0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }
    /*
     *  NOTE : there is no need to get the timer callback thread to wake
     *  up and recalculate.  If this timer is the next to expire, then
     *  the timer callback thread will wake up but not find any timers to
     *  callback and will just go back to sleep again anyway.
     */

    /*
     *  NOTE2 : We cancel a timer by doing a linear search for the timer id.
     *  This is not terribly efficient but is the safest way to ensure that
     *  cancellations do not cancel the wrong timer by mistake.  Also we
     *  assume timer cancellation does not occur often.  If the timer to
     *  be cancelled is not found, an error is logged.
     */

    for (i = 0; i < ixOsalHigestTimeSlotUsed; i++)
    {
        if (ixOsalTimers[i].inUse && ixOsalTimers[i].id == id)
        {
            ixOsalTimers[i].inUse = FALSE;
            break;
        }
    }

    status = ixOsalSemaphorePost (&ixOsalCriticalSectSem);
    if (status != IX_SUCCESS)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "ixOsalTimerCancel: fail to free semaphore \n", 0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    return IX_SUCCESS;
}
Example #5
0
/**
 * @ingroup IxTimeSyncAccCodelet
 *
 * @fn ixTimeSyncAccCodeletPTPMsgTransmit ()
 *
 * @brief  Transmit Sync message from master port and Delay_Req message
 *	   from slave port every 2 seconds.  
 *
 * @return void
 */
PRIVATE void
ixTimeSyncAccCodeletPTPMsgTransmit ()
{
	IX_OSAL_MBUF *mBufPtr;
	IxEthAccPortId portId = 0; 
	IxTimeSyncAcc1588PTPPort tsChannel;
	IxTimeSyncAcc1588PTPMsgType txMsgType;
	IxTimeSyncAcc1588PTPPortMode tsChannelMode;

	/* clear PTP message transmission halt flag */
	ixTimeSyncAccCodeletTxHalt = FALSE;

	for (tsChannel = IX_TIMESYNCACC_NPE_A_1588PTP_PORT; 
	     tsChannel < IX_TIMESYNCACC_CODELET_MAX_TS_CHANNELS; 
	     tsChannel++)
	{
		
		portId = ixTimeSyncAccCodeletPortIdList[tsChannel];
		tsChannelMode = ixTimeSyncAccCodeletConfigPtr->tsChannelMode[tsChannel];
		txMsgType = ixTimeSyncAccCodeletPTPMsgTypeList[tsChannelMode]; 
	
		/* build PTP message */
		ixTimeSyncAccCodeletPTPMsgBuild (txMsgType);

		if (IX_SUCCESS != ixTimeSyncAccCodeletPortConfigure (portId))
		{
			ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPTPMsgTransmit: failed to configure port %d\n", 
				portId, 0, 0, 0, 0, 0);

			/* terminate time sync codelet execution */
			ixTimeSyncAccCodeletUninit ();

			return;
		}
   
		if (IX_ETH_ACC_SUCCESS != ixEthAccPortEnable (portId))
		{
			ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPTPMsgTransmit: failed to enable port %d\n", 
				portId, 0, 0, 0, 0, 0);
			
			/* terminate time sync codelet execution */
			ixTimeSyncAccCodeletUninit ();

			return;
		} 

		mBufPtr = ixTimeSyncAccCodeletGlobalMBuf[portId];

		if (NULL == mBufPtr)
		{
	  		ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPTPMsgTransmit: NULL mBuf pointer, port Id %d\n", 
				portId, 0, 0, 0, 0, 0);

			/* terminate time sync codelet execution */
			ixTimeSyncAccCodeletUninit ();

			return;
		}
		
		/* copy PTP message data to mBuf's data buffer */	
		ixOsalMemCopy (IX_OSAL_MBUF_MDATA(mBufPtr), 
			ixTimeSyncAccCodeletPtpMsgData, 
			IX_TIMESYNCACC_CODELET_UDP_FRAME_LEN);

	} /* end of for loop */

	if (IX_SUCCESS != ixOsalSemaphoreInit (&ixTimeSyncAccCodeletSemId, IX_TIMESYNCACC_CODELET_MAX_TS_CHANNELS))
	{
		ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPTPMsgTransmit: failed to create semaphore\n",
			0, 0, 0, 0, 0, 0);
		
		/* terminate time sync codelet execution */
		ixTimeSyncAccCodeletUninit ();

		return;
	}
	
	do 
	{
		/* halt PTP message transmission */
		if (TRUE == ixTimeSyncAccCodeletTxHalt)
		{
			ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletPTPMsgTransmit: PTP message transmission was halted\n",
				0, 0, 0, 0, 0, 0);

			return;
		}

		/* sleep and wait for interval time to elapse before transmitting next PTP message */
		ixOsalSleep (IX_TIMESYNCACC_CODELET_PTP_MSG_XMIT_INTERVAL);

		for (portId = IX_ETH_PORT_1; portId <= IX_ETH_PORT_3; portId++)
		{
			if (IX_SUCCESS != ixOsalSemaphoreWait (&ixTimeSyncAccCodeletSemId, IX_TIMESYNCACC_CODELET_PTP_MSG_XMIT_INTERVAL))
			{
				ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPTPMsgTransmit: PTP message transmission error at port %d\n",
					portId, 0, 0, 0, 0, 0);
				
				/* terminate time sync codelet execution */
				ixTimeSyncAccCodeletUninit ();

				return;
	
			}

			if (IX_ETH_ACC_SUCCESS != ixEthAccPortTxFrameSubmit (portId, 
									ixTimeSyncAccCodeletGlobalMBuf[portId], 
									IX_ETH_ACC_TX_DEFAULT_PRIORITY))
			{
				ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPTPMsgTransmit: failed to transmit PTP message from port %d\n", 
					portId, 0, 0, 0, 0, 0);

				
				/* terminate time sync codelet execution */
				ixTimeSyncAccCodeletUninit ();

				return;
			}
		} /* end of for loop */
				
	} while (TRUE);

} /* end of ixTimeSyncAccCodeletPTPMsgTransmit function */
Example #6
0
/**
 * @brief Ethernet event processor loop
 *
 * Extracts at most EVENT_PROCESSING_LIMIT batches of events and
 * sends them for processing to @ref ixEthDBProcessEvent().
 * Triggers port updates which normally follow learning events.
 *
 * @warning do not call directly, executes in separate thread
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
void ixEthDBEventProcessorLoop(void *unused1)
{
    IxEthDBPortMap triggerPorts;
    IxEthDBPortId portIndex;

    ixEthDBEventProcessorRunning = TRUE;

    IX_ETH_DB_EVENTS_TRACE("DB: (Events) Event processor loop was started\n");

    while (!ixEthDBLearningShutdown)
    {
        BOOL keepProcessing    = TRUE;
        UINT32 processedEvents = 0;

        if (ixEthDBEventProcessorPausing == TRUE)
	{
          /* 100 ms*/
          ixOsalSleep(100);
          continue;
        } 

        IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Waiting for new learning event...\n");

        ixOsalSemaphoreWait(&eventQueueSemaphore, IX_OSAL_WAIT_FOREVER);

        IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Received new event\n");

        if (!ixEthDBLearningShutdown)
        {
            /* port update handling */
            SET_EMPTY_DEPENDENCY_MAP(triggerPorts);

            while (keepProcessing)
            {
                PortEvent local_event;
                UINT32 intLockKey;

                /* lock queue */
                ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);

                /* lock NPE interrupts */
                intLockKey = ixOsalIrqLock();

                /* extract event */
                local_event = *(QUEUE_TAIL(&eventQueue));

                SHIFT_UPDATE_QUEUE(&eventQueue);

                ixOsalIrqUnlock(intLockKey);

                ixOsalMutexUnlock(&eventQueueLock);

                IX_ETH_DB_EVENTS_TRACE("DB: (Events) Processing event with ID 0x%X\n", local_event.eventType);

                ixEthDBProcessEvent(&local_event, triggerPorts);

                processedEvents++;

                if (processedEvents > EVENT_PROCESSING_LIMIT /* maximum burst reached? */
                    || ixOsalSemaphoreTryWait(&eventQueueSemaphore) != IX_SUCCESS) /* or empty queue? */
                {
                    keepProcessing = FALSE;
                }
            }

            /* Added a pause check here to prevent NPE message
             * from being sent from ixEthDBUpdatePortLearningTrees() 
             */ 
	    while (ixEthDBEventProcessorPausing == TRUE)
	      {
		/* 100 ms*/
		ixOsalSleep(100);		
	      } 
	    
            ixEthDBUpdatePortLearningTrees(triggerPorts);
        }
    }

    /* turn off automatic updates */
    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
    {
        ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE;
    }

    ixEthDBEventProcessorRunning = FALSE;
}
Example #7
0
PUBLIC IX_STATUS
ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout)
{
    return ixOsalSemaphoreWait((IxOsalSemaphore *) mutex, timeout);
}
Example #8
0
/* 
 * Attempt to get semaphore, return immediately,
 * no error info because users expect some failures
 * when using this API.
 */
PUBLIC IX_STATUS
ixOsalSemaphoreTryWait(IxOsalSemaphore *sid)
{
    return ixOsalSemaphoreWait(sid,  IX_OSAL_WAIT_NONE);
}
Example #9
0
PRIVATE IX_STATUS
createNewTimer (IxOsalVoidFnVoidPtr func, void *param, UINT32 priority,
    UINT32 interval, BOOL isRepeating, UINT32 * timerId)
{
    UINT32 i;
    IX_STATUS status = IX_SUCCESS;
    int osTicks;
    IxOsalTimeval timeVal;

    /*
     * Check if callback is NULL 
     */
    if (func == NULL)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "client registered a NULL callback function\n", 0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    osTicks = ixOsalSysClockRateGet ();
    /*
     * Figure out how many milisecond per tick and compare against interval 
     */
    if (interval < (UINT32) (1000 / osTicks))
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "client requested time interval (%d) finer than clock ticks\n",
            interval, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    /*
     * Increment timerId 
     */
    *timerId = ++lastTimerId;

    status =
        ixOsalSemaphoreWait (&ixOsalCriticalSectSem, IX_OSAL_WAIT_FOREVER);
    if (status != IX_SUCCESS)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "createNewTimer  fail to get semaphore \n", 0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    for (i = 0; i < IX_OSAL_MAX_TIMERS; i++)
    {
        if (!ixOsalTimers[i].inUse)
        {
            break;
        }
    }

    if ((i >= IX_OSAL_TIMER_WARNING_THRESHOLD)
        && (ixOsalThresholdErr == FALSE))
    {
        /*
         * This error serves as an early indication that the number of
         * available timer slots will need to be increased. This is done
         * by increasing IX_OSAL_MAX_TIMERS
         */
        ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT,
            "Timer threshold reached. Only %d timer slots now available\n",
            IX_OSAL_MAX_TIMERS - i, 0, 0, 0, 0, 0);
        ixOsalThresholdErr = TRUE;
    }

    if (i == IX_OSAL_MAX_TIMERS)
    {
        /*
         *  If you get this error, increase MAX_TIMERS above 
         */
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "Out of timer slots %d used - request ignored\n",
            i, 0, 0, 0, 0, 0);
        status = IX_FAIL;
    }
    else
    {
        ixOsalTimers[i].inUse = TRUE;

        IX_OSAL_MS_TO_TIMEVAL (interval, &timeVal);

        ixOsalTimers[i].period = timeVal;
        ixOsalTimers[i].isRepeating = isRepeating;
        ixOsalTimeGet (&(ixOsalTimers[i].expires));
        IX_OSAL_TIME_ADD ((ixOsalTimers[i].expires), (ixOsalTimers[i].period))
            ixOsalTimers[i].priority = priority;
        ixOsalTimers[i].callback = func;
        ixOsalTimers[i].callbackParam = param;
        ixOsalTimers[i].id = *timerId;

        if ((i) >= ixOsalHigestTimeSlotUsed)
        {
            ixOsalHigestTimeSlotUsed = i + 1;
        }

        status = ixOsalSemaphorePost (&ixOsalTimerRecalcSem);
        if (status != IX_SUCCESS)
        {
            ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
                "createNewTimer:  fail to release semaphore \n",
                0, 0, 0, 0, 0, 0);
            return IX_FAIL;
        }

    }

    status = ixOsalSemaphorePost (&ixOsalCriticalSectSem);
    if (status != IX_SUCCESS)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "createNewTimer:  fail to release semaphore: ixOsalCriticalSectSem \n",
            0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    return status;
}