PUBLIC IX_STATUS ixOsalOemInit (void) { /* * Check flag */ if (IxOsalOemInitialized == TRUE) { ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, "ixOsalOemInit(): already initialized. \n", 0, 0, 0, 0, 0, 0); return IX_SUCCESS; } ixOsalOstsRegAddr = (volatile UINT32 *) IX_OSAL_MEM_MAP (IX_OSAL_IXP400_OSTS_PHYS_BASE, 4); if (ixOsalOstsRegAddr == NULL) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalOemInit(): Fail to map time stamp register. \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } IxOsalOemInitialized = TRUE; return IX_SUCCESS; }
PUBLIC IX_STATUS ixOsalRepeatingTimerSchedule (IxOsalTimer * timer, UINT32 period, UINT32 priority, IxOsalVoidFnVoidPtr callback, void *param) { IX_STATUS ixStatus = IX_FAIL; if (ixOsalTimerInited == FALSE) { /* * Init timer */ ixStatus = timerInit (); if (ixStatus != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalRepeatingTimerSchedule: fail to init timer \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } ixOsalTimerInited = TRUE; } ixStatus = createNewTimer (callback, param, priority, period, TRUE, timer); if (ixStatus != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalRepeatingTimerSchedule: fail to create timer \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } return IX_SUCCESS; }
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; }
PRIVATE void ixEthAccCodeletLoopbackRxCB(UINT32 cbTag, IX_OSAL_MBUF** mBufPtr) { /* Transmit the buffer back on the port it was received on*/ if(cbTag < IX_ETHACC_CODELET_MAX_PORT ) { while (NULL != *mBufPtr) { ixEthAccCodeletStats[cbTag].rxCount++; /* transmit the frame on the same port */ if(ixEthAccPortTxFrameSubmit(cbTag, *mBufPtr, IX_ETH_ACC_TX_DEFAULT_PRIORITY) != IX_ETH_ACC_SUCCESS) { ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Tx Buffer submission failure port %d\n", cbTag, 0, 0, 0, 0, 0); } /* move to next buffer received */ mBufPtr++; } } else { ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Invalid Rx callback tag %d in Sw Loopback Operation\n", cbTag, 0, 0, 0, 0, 0); } }
PRIVATE void ixEthAccCodeletLoopbackTxCB(UINT32 cbTag, IX_OSAL_MBUF* mBufPtr) { /* Put the mbuf back in the rx free pool */ if(cbTag < IX_ETHACC_CODELET_MAX_PORT) { ixEthAccCodeletStats[cbTag].txCount++; /* reset the frame length to the length at pool setup */ ixEthAccCodeletMbufChainSizeSet(mBufPtr); if(ixEthAccPortRxFreeReplenish(cbTag, mBufPtr) != IX_SUCCESS) { ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Error replenishing RX free queue on port %d\n", cbTag, 0, 0, 0, 0, 0); } } else { ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Invalid Tx callback tag %d in RxSink Operation\n", cbTag, 0, 0, 0, 0, 0); } }
/** * @ingroup IxTimeSyncAccCodelet * * @fn ixTimeSyncAccCodeletPTPMsgShow ( BOOL receive, IxTimeSyncAcc1588PTPPort channel, IxTimeSyncAccPtpMsgData *ptpMsgData) * * @brief Display PTP message type and relevant information * * @param * receive BOOL [in] - direction of detected message. * - FALSE : PTP message is transmitted. * - TRUE : PTP message is received. * * channel IxTimeSyncAcc1588PTPPort [in] - channel number * * ptpMsgData IxTimeSyncAccPtpMsgData* [in] - pointer to * IxTimeSyncAccPtpMsgData buffer. * * @return void */ PRIVATE void ixTimeSyncAccCodeletPTPMsgShow ( BOOL receive, IxTimeSyncAcc1588PTPPort tsChannel, IxTimeSyncAccPtpMsgData *ptpMsgData ) { /* get the operation mode at a given channel */ IxTimeSyncAcc1588PTPPortMode tsChannelMode = ixTimeSyncAccCodeletConfigPtr->tsChannelMode[tsChannel]; /* PTP message is detected */ ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletPTPMsgShow: %s channel (%s) %s %s Msg @ system time %08x %08x\n", (UINT32) (ixTimeSyncAccCodeletTSChannelLabel[tsChannel]), (UINT32) (ixTimeSyncAccCodeletTSChannelModeLabel[tsChannelMode]), (UINT32) (receive ? "received" : "transmitted"), (UINT32) (ixTimeSyncAccCodeletPTPMessageLabel[ptpMsgData->ptpMsgType]), ptpMsgData->ptpTimeStamp.timeValueHighWord, ptpMsgData->ptpTimeStamp.timeValueLowWord); if (TRUE == receive) { /* show sequence number and UuId of received message */ ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletPTPMsgShow: \tptpSequenceNumber %08x ptpUuid %08x %08x\n", ptpMsgData->ptpSequenceNumber, ptpMsgData->ptpUuid.uuidValueHighHalfword, ptpMsgData->ptpUuid.uuidValueLowWord, 0, 0, 0); } } /* end of ixTimeSyncAccCodeletPTPMsgShow function */
PRIVATE IX_STATUS ixTimeSyncAccCodeletDispatcherStart () { /* get dispatcher function pointer, this should be initialized once */ ixQMgrDispatcherLoopGet(&ixTimeSyncAccCodeletDispatcherFunc); if (NULL == ixTimeSyncAccCodeletDispatcherFunc) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletDispatcherStart: failed to get dispatcher function pointer\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } /* Hook the QM QLOW dispatcher to the interrupt controller */ if (IX_SUCCESS != ixOsalIrqBind(IX_OSAL_IXP400_QM1_IRQ_LVL, (IxOsalVoidFnVoidPtr)(ixTimeSyncAccCodeletDispatcherFunc), (void *)IX_QMGR_QUELOW_GROUP)) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletDispatcherStart: failed to hook QM QLOW dispatcher to the interrupt controller\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } return (IX_SUCCESS); } /* end of ixTimeSyncAccCodeletDispatcherStart function */
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); } } }
/* * Function definition: ixNpeDlNpeMgrStatsShow */ void ixNpeDlNpeMgrStatsShow (void) { ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "\nixNpeDlNpeMgrStatsShow:\n" "\tInstruction Blocks loaded: %u\n" "\tData Blocks loaded: %u\n" "\tState Information Blocks loaded: %u\n" "\tCritical NPE errors: %u\n" "\tCritical Microcode errors: %u\n", ixNpeDlNpeMgrStats.instructionBlocksLoaded, ixNpeDlNpeMgrStats.dataBlocksLoaded, ixNpeDlNpeMgrStats.stateInfoBlocksLoaded, ixNpeDlNpeMgrStats.criticalNpeErrors, ixNpeDlNpeMgrStats.criticalMicrocodeErrors, 0); ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "\tSuccessful NPE Starts: %u\n" "\tSuccessful NPE Stops: %u\n" "\tSuccessful NPE Resets: %u\n\n", ixNpeDlNpeMgrStats.npeStarts, ixNpeDlNpeMgrStats.npeStops, ixNpeDlNpeMgrStats.npeResets, 0,0,0); ixNpeDlNpeMgrUtilsStatsShow (); }
/* * This function unmaps a previously mapped I/O memory zone using * the cookie obtained in the mapping operation. The memory zone in question * becomes unavailable to the caller once unmapped and the cookie should be * discarded. * * This function cannot fail if the given parameter is correct and does not * return a value. * * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP * instead. */ PUBLIC void ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType) { IxOsalMemoryMap *map; if (endianType == IX_OSAL_LE) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n", 0, 0, 0, 0, 0, 0); return; } if (requestedAddress == 0) { /* * invalid virtual address */ return; } map = ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS, endianType); if (map != NULL) { if (map->refCount > 0) { /* * decrement reference count */ map->refCount--; if (map->refCount == 0) { /* * no longer used, deallocate */ if (map->type == IX_OSAL_DYNAMIC_MAP && map->unmapFunction != NULL) { map->unmapFunction (map); } } } } else { ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDERR, "OSAL: ixOsServMemUnmap didn't find the requested map " "[virt addr 0x%x: endianType %d], ignoring call\n", requestedAddress, endianType, 0, 0, 0, 0); } }
PUBLIC void ixOsalMbufDataPtrReset (IX_OSAL_MBUF * bufPtr) { IX_OSAL_MBUF_POOL *poolPtr; UINT8 *poolDataPtr; if (bufPtr == NULL) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalBuffPoolBufDataPtrReset" ": ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0); return; } poolPtr = (IX_OSAL_MBUF_POOL *) IX_OSAL_MBUF_NET_POOL (bufPtr); poolDataPtr = poolPtr->dataMemPtr; if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC) { if (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) != IX_OSAL_MBUF_SYS_SIGNATURE) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalBuffPoolBufDataPtrReset" ": invalid mbuf, cannot reset mData pointer\n", 0, 0, 0, 0, 0, 0); return; } IX_OSAL_MBUF_MDATA (bufPtr) = (UINT8*)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (bufPtr); } else { if (poolDataPtr) { unsigned int bufSize = poolPtr->bufDataSize; unsigned int bufDataAddr = (unsigned int) IX_OSAL_MBUF_MDATA (bufPtr); unsigned int poolDataAddr = (unsigned int) poolDataPtr; /* * the pointer is still pointing somewhere in the mbuf payload. * This operation moves the pointer to the beginning of the * mbuf payload */ bufDataAddr = ((bufDataAddr - poolDataAddr) / bufSize) * bufSize; IX_OSAL_MBUF_MDATA (bufPtr) = &poolDataPtr[bufDataAddr]; } else { ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "ixOsalBuffPoolBufDataPtrReset" ": cannot be used if user supplied NULL pointer for pool data area " "when pool was created\n", 0, 0, 0, 0, 0, 0); return; } } }
PUBLIC void ixTimeSyncAccCodeletUninit () { int moduleId; IxOsalVoidFnPtr func; IxTimeSyncAccCodeletUninitFuncPtr func1; if (TRUE == ixTimeSyncAccCodeletTerminate) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletUninit: timeSyncAcc codelet is either not loaded or in the process of being terminated\n", 0, 0, 0, 0, 0, 0); return; } /* set termination flag */ ixTimeSyncAccCodeletTerminate = TRUE; /* unload every supporting modules and free all resources */ for (moduleId = IX_TIMESYNCACC_CODELET_TX_PTP; moduleId >= IX_TIMESYNCACC_CODELET_MBUF_ALLOC; moduleId--) { if (TRUE == ixTimeSyncAccCodeletUninitFuncMap[moduleId].initialized) { if (IX_TIMESYNCACC_CODELET_INVALID_PARAM == ixTimeSyncAccCodeletUninitFuncMap[moduleId].funcParameter) { func = (IxOsalVoidFnPtr)ixTimeSyncAccCodeletUninitFuncMap[moduleId].funcPtr; (*func)(); } else { func1 = (IxTimeSyncAccCodeletUninitFuncPtr)ixTimeSyncAccCodeletUninitFuncMap[moduleId].funcPtr; (*func1)(ixTimeSyncAccCodeletUninitFuncMap[moduleId].funcParameter); } ixTimeSyncAccCodeletUninitFuncMap[moduleId].initialized = FALSE; } } /* unload ethDB */ if (IX_ETH_DB_SUCCESS != ixEthDBUnload ()) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletUninit: failed to unload ethDB\n", 0, 0, 0, 0, 0, 0); } /* wait for a while for the codelet to disable target time */ ixOsalSleep (IX_TIMESYNCACC_CODELET_TARGET_TIME_HIT_INTERVAL); ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletUninit: timeSyncAcc codelet execution was terminated\n", 0, 0, 0, 0, 0, 0); return; } /* end of ixTimeSyncAccCodeletUninit function */
PRIVATE IX_STATUS timerInit (void) { IxOsalThread taskId; IX_STATUS ixStatus; IxOsalThreadAttr timerThreadAttr; ixStatus = ixOsalSemaphoreInit (&ixOsalCriticalSectSem, IX_OSAL_TIMER_SEM_AVAILABLE); if (ixStatus != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Error creating critical section semaphore\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } ixStatus = ixOsalSemaphoreInit (&ixOsalTimerRecalcSem, IX_OSAL_TIMER_SEM_AVAILABLE); if (ixStatus != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Error creating timer recalc semaphore\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } timerThreadAttr.stackSize = 10 * 1024; timerThreadAttr.priority = 90; timerThreadAttr.name = ixOsalTimerThreadName; ixStatus = ixOsalThreadCreate (&taskId, &timerThreadAttr, (IxOsalVoidFnVoidPtr) timerLoop, NULL); if (ixStatus != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "timerInit: fail to create timer thread. \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } ixStatus = ixOsalThreadStart (&taskId); if (ixStatus != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Error creating timerLoop task\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } return IX_SUCCESS; }
/** * @ingroup IxTimeSyncAccCodelet * * @fn ixTimeSyncAccCodeletNewThreadCreate ( IxOsalVoidFnPtr func, char *label) * * @brief Spawn a thread to execute given function * * @param * func IxOsalVoidFnPtr [in] - pointer to the function that will be * executed after the thread is spawned. * @param * label char* [in] - pointer to the Thread name's buffer * * @return IX_STATUS * @li IX_SUCCESS - create and start Thread successfully * @li IX_FAIL - fail */ PRIVATE IX_STATUS ixTimeSyncAccCodeletNewThreadCreate ( IxOsalVoidFnPtr func, char *label) { IxOsalThread threadId; IxOsalThreadAttr threadAttr; /* check the validity of function pointer */ if (NULL == func) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletNewThreadCreate: NULL function pointer\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } /* check the validity of Thread name's buffer pointer */ if (NULL == label) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletNewThreadCreate: NULL Thread name's pointer\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } /* zero out the thread attribute buffer */ ixOsalMemSet ((void *)&threadAttr, 0, sizeof (IxOsalThreadAttr)); /* setup thread attribute */ threadAttr.name = label; threadAttr.priority = IX_OSAL_DEFAULT_THREAD_PRIORITY; if (IX_SUCCESS != ixOsalThreadCreate (&threadId, &threadAttr, (IxOsalVoidFnVoidPtr)func, NULL)) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletNewThreadCreate: Failed to spawn %s thread\n", (UINT32) label, 0, 0, 0, 0, 0); return IX_FAIL; } if (IX_SUCCESS != ixOsalThreadStart (&threadId)) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletNewThreadCreate: Failed to start %s thread\n", (UINT32) label, 0, 0, 0, 0, 0); return IX_FAIL; } return IX_SUCCESS; } /* end of ixTimeSyncAccCodeletNewThreadCreate function */
/* * Function definition : ixDmaAccCodeletDispatcherStart() * See header file for documentation. */ PRIVATE IX_STATUS ixDmaAccCodeletDispatcherStart(BOOL useInterrupt) { IxOsalThreadAttr threadAttr; char *pThreadName = "Dispatcher"; ixQMgrDispatcherLoopGet(&ixDmaAccCodeletDispatcherFunc); if(useInterrupt) /* Interrupt mode */ { /* * Hook the QM QLOW dispatcher to the interrupt controller. * IX_QMGR_QUELOW_GROUP refers to Queues 0-31 * Dma NPE A: queues 19 & 20; NPE B: 24 & 26; NPE B: 25 & 27 */ if (ixOsalIrqBind(IX_OSAL_IXP400_QM1_IRQ_LVL, (IxOsalVoidFnVoidPtr)ixDmaAccCodeletDispatcherFunc, (void *)IX_QMGR_QUELOW_GROUP) != IX_SUCCESS) { printf("\nFailed to bind to QM1 interrupt"); return (IX_FAIL); } } else /* Polled mode */ { threadAttr.name = pThreadName; threadAttr.stackSize = IX_DMA_CODELET_QMGR_STACK_SIZE; threadAttr.priority = IX_DMA_CODELET_QMR_PRIORITY; if (ixOsalThreadCreate(&ixDmaAccCodeletDispatchId, &threadAttr, (IxOsalVoidFnVoidPtr)ixDmaAccCodeletDispatcherPoll, NULL ) != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "\nError spawning dispatch task", 0,0,0,0,0,0); return (IX_FAIL); } if (ixOsalThreadStart (&ixDmaAccCodeletDispatchId) != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "\nError starting spawing dispatch task", 0,0,0,0,0,0); return (IX_FAIL); } } return (IX_SUCCESS); }
PUBLIC IX_STATUS ixOsalMemMapInit (IxOsalMemoryMap *map, UINT32 numElement) { UINT32 i; static BOOL initialized = FALSE; if (initialized) { ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, "ixOsalMemMapInit: Already initialized", 0, 0, 0, 0, 0, 0); return IX_SUCCESS; } for (i = 0; i < numElement; i++) { IxOsalMemoryMap *localmap = &map[i]; /* Add runtime determined dynamic expansion bus mapping info */ if (!strcmp(localmap->name, IX_OSAL_MEMMAP_RESERVED)) { localmap->type = IX_OSAL_DYNAMIC_MAP; localmap->physicalAddress = IX_OSAL_IXP400_EXP_BUS_PHYS_BASE; localmap->size = IX_OSAL_IXP400_EXP_BUS_MAP_SIZE; localmap->virtualAddress = 0; localmap->mapFunction = ixOsalLinuxMemMap; localmap->unmapFunction = ixOsalLinuxMemUnmap; localmap->refCount = 0; localmap->mapEndianType = IX_OSAL_BE | IX_OSAL_LE_AC; strcpy(localmap->name, "exp bus"); break; } } if (i == numElement) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalMemMapInit(): Fail to initialize memory map.\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } initialized = TRUE; return IX_SUCCESS; }
IX_STATUS ixOsalSemaphoreWait (IxOsalSemaphore * sid, INT32 timeout) { int retVal; UINT32 ticks; if ( (timeout == IX_OSAL_WAIT_FOREVER) || (timeout == IX_OSAL_WAIT_NONE)) { retVal = semTake (*(SEM_ID *) sid, timeout); } else if (timeout > 0) { ticks = (ixOsalSysClockRateGet () * timeout) / 1000; retVal = semTake (*(SEM_ID *) sid, ticks); } else { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalSemaphoreWait(): Illegal timeout value. \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } if (retVal != OK) { return IX_FAIL; } return IX_SUCCESS; }
PUBLIC IX_OSAL_MBUF * ixOsalMbufFree (IX_OSAL_MBUF * bufPtr) { int lock; IX_OSAL_MBUF_POOL *poolPtr; IX_OSAL_MBUF *nextBufPtr = NULL; /* * check parameters */ if (bufPtr == NULL) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalMbufFree(): " "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0); return NULL; } lock = ixOsalIrqLock (); #ifdef IX_OSAL_BUFFER_FREE_PROTECTION /* Prevention for Buffer freed more than once*/ if(!IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr)) { ixOsalIrqUnlock (lock); return NULL; } IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr); #endif poolPtr = IX_OSAL_MBUF_NET_POOL (bufPtr); /* * check the mbuf wrapper signature (if mbuf wrapper was used) */ if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC) { IX_OSAL_ENSURE ( (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) == IX_OSAL_MBUF_SYS_SIGNATURE), "ixOsalBuffPoolBufFree: ERROR - Invalid mbuf signature."); } nextBufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr); IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr) = poolPtr->nextFreeBuf; poolPtr->nextFreeBuf = bufPtr; /* * update the number of free buffers in the pool */ poolPtr->freeBufsInPool++; ixOsalIrqUnlock (lock); return nextBufPtr; }
PRIVATE void ixEthAccCodeletSwBridgeQoSUntaggedToTaggedRxCB(UINT32 cbTag, IX_OSAL_MBUF* mBufPtr, UINT32 destPortId) { IxEthAccPortId thisPortId = (IxEthAccPortId)(cbTag & 0xffff); IxEthAccPortId otherPortId = (IxEthAccPortId)(cbTag>>16); IxEthAccTxPriority priority = (IX_ETH_DB_GET_QOS_PRIORITY(IX_ETHACC_CODELET_VLANID_DEFAULT)); ixEthAccCodeletStats[thisPortId].rxCount++; /* Set the VLAN information for this frame : the outgoing frame * is tagged with the default tagging rules for this port */ IX_ETHACC_NE_FLAGS(mBufPtr) = IX_ETHACC_NE_VLANENABLEMASK; IX_ETHACC_NE_VLANTCI(mBufPtr) = IX_ETHACC_CODELET_VLANID_DEFAULT; /* Transmit the buffer on the other port */ if(ixEthAccPortTxFrameSubmit(otherPortId, mBufPtr, priority) !=IX_ETH_ACC_SUCCESS) { ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "SwBridgeQos: Tx Buffer submission failed on port %u\n", (UINT32)(1 - cbTag), 0, 0, 0, 0, 0); } }
/** * @fn void ixEthAccCodeletRxSinkRxCB() * * Recieve callback for Rx sink * * @return void */ PRIVATE void ixEthAccCodeletRxSinkRxCB(UINT32 cbTag, IX_OSAL_MBUF** mBufPtr) { while (NULL != *mBufPtr) { ixEthAccCodeletStats[cbTag].rxCount++; #ifdef IX_ETHACC_CODELET_TXGENRXSINK_VERIFY IX_ETHACC_CODELET_DATA_VERIFY(IX_OSAL_MBUF_MDATA(*mBufPtr), compData); /* After reading the payload, invalidate it before replenish */ IX_OSAL_CACHE_INVALIDATE(IX_OSAL_MBUF_MDATA(*mBufPtr), IX_OSAL_MBUF_MLEN(*mBufPtr)); #endif ixEthAccCodeletMbufChainSizeSet(*mBufPtr); /* Return mBuf to free queue on same port */ if(ixEthAccPortRxFreeReplenish(cbTag, *mBufPtr) != IX_SUCCESS) { ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Error replenishing RX free q in TxGen-RxSink\n", 0, 0, 0, 0, 0, 0); } /* move to next buffer received */ mBufPtr++; } }
void ixAtmUtilsMbufPoolFreeGet (UINT32 bufSize, UINT32 *avail) { IX_OSAL_MBUF_POOL *poolPtr = NULL; unsigned i,numPools; numPools = NUMELEMS (poolInfo); for (i = 0; i < numPools; i++) { if (poolInfo[i].bufSize >= bufSize) { poolPtr = poolInfo[i].poolPtr; break; } } if (poolPtr == NULL) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR,IX_OSAL_LOG_DEV_STDERR, "ixAtmUtilsMbufPoolFreeGet - Invalid bufSize specified\n", 0, 0, 0, 0, 0, 0); *avail = 0; return; } *avail = poolPtr->freeBufsInPool; }
PRIVATE void ixEthAccCodeletSwBridgeQoSTxCB(UINT32 cbTag, IX_OSAL_MBUF* mBufPtr) { IxEthAccPortId thisPortId = (IxEthAccPortId)(cbTag & 0xffff); IxEthAccPortId otherPortId = (IxEthAccPortId)(cbTag>>16); /* * Put the mbuf on the rx freeQ of the other port since it was * received there initially. */ ixEthAccCodeletStats[thisPortId].txCount++; /* one tx that was pending is now complete */ pendingTx[thisPortId]--; /* reset the frame length */ ixEthAccCodeletMbufChainSizeSet(mBufPtr); /* replenish the other port */ if(ixEthAccPortRxFreeReplenish(otherPortId, mBufPtr) !=IX_SUCCESS) { ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "SwBridgeQos: Error replenishing RX free q for port %u\n", (UINT32)(1 - cbTag), 0, 0, 0, 0, 0); } }
/******************************************************************** * ixEthAccMiiInit */ IxEthAccStatus ixEthAccMiiInit() { if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS) { return IX_ETH_ACC_FAIL; } /* Use one MAC coprocessor for MII since any MAC can access all PHYs. * Check which NPE MAC coprocessor is available starting with NPEB. * If NPEB is unavailable, check NPEC, then NPEA. * If none of the three work, return failure. */ miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETH_MAC_B0_MAP_SIZE); if (miiBaseAddressVirt == 0) { ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT, "EthAcc: Could not map MII I/O mapped memory\n", 0, 0, 0, 0, 0, 0); return IX_ETH_ACC_FAIL; } REG_WRITE(miiBaseAddressVirt, IX_ETH_ACC_MAC_CORE_CNTRL, IX_ETH_ACC_CORE_MDC_EN); return IX_ETH_ACC_SUCCESS; }
/* * Function definition : ixDmaAccCodeletNpeInit() * See header file for documentation. */ PRIVATE IX_STATUS ixDmaAccCodeletNpeInit(IxNpeDlNpeId npeId) { UINT32 imageId; /* Storage for single image Id */ /* Check for invalid npeId value */ /* Set the image Id for DMA component */ switch (npeId) { case IX_NPEDL_NPEID_NPEA : imageId = IX_DMA_CODELET_NPE_A_IMAGEID; break; case IX_NPEDL_NPEID_NPEB : imageId = IX_DMA_CODELET_NPE_B_IMAGEID; break; case IX_NPEDL_NPEID_NPEC : imageId = IX_DMA_CODELET_NPE_C_IMAGEID; break; default: /* Invalid NPE ID */ ixOsalLog (IX_OSAL_LOG_LVL_ALL, IX_OSAL_LOG_DEV_STDOUT, "\nDMAAccDemoNpeInit : invalid Npe ID.", 0,0,0,0,0,0); return (IX_FAIL); } /* end of switch(npeId) */ /* Download NPE code */ if(ixNpeDlNpeInitAndStart(imageId) != IX_SUCCESS) { printf("\nNPE download failed"); return(IX_FAIL); } return(IX_SUCCESS); }
PRIVATE void callTimerCallback (IxOsalVoidFnVoidPtr callback, void *callbackParam) { IxOsalTimeval timevalCbBegin, timevalCbFinish; static BOOL errorReported = FALSE; ixOsalTimerCbCnt++; ixOsalTimeGet (&timevalCbBegin); callback (callbackParam); ixOsalTimeGet (&timevalCbFinish); IX_OSAL_TIME_SUB (timevalCbFinish, timevalCbBegin); if ((timevalCbFinish.nsecs > IX_MAX_TIMER_CALLBACK_TIME) || (timevalCbFinish.secs > 0)) { if (!errorReported) { ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "Slow timer callback - %d Secs, %d nSecs \n", timevalCbFinish.secs, timevalCbFinish.nsecs, 0, 0, 0, 0); errorReported = TRUE; } } }
PUBLIC IX_STATUS ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout) { UINT32 ticks; if (timeout > 0) { ticks = (ixOsalSysClockRateGet () * timeout) / 1000; return IX_OSAL_MAP_VX_RETCODE (semTake ((*mutex), (INT32) ticks)); } else if (timeout == IX_OSAL_WAIT_FOREVER) { return IX_OSAL_MAP_VX_RETCODE (semTake ((*mutex), WAIT_FOREVER)); } else if (timeout == IX_OSAL_WAIT_NONE) { return IX_OSAL_MAP_VX_RETCODE (semTake ((*mutex), NO_WAIT)); } else { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalMutexLock(): ERROR - wrong timeout value = %d \n", timeout, 0, 0, 0, 0, 0); return IX_FAIL; } }
/* * Function definition: ixOsalBuffPoolUninit */ PUBLIC IX_STATUS ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool) { if (!pool) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalBuffPoolUninit: NULL ptr \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } if (pool->freeBufsInPool != pool->totalBufsInPool) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalBuffPoolUninit: need to return all ptrs to the pool first! \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } if (pool->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC) { #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY UINT32 i; IX_OSAL_MBUF* pBuf; pBuf = pool->nextFreeBuf; /* Freed the Buffer one by one till all the Memory is freed*/ for (i= pool->freeBufsInPool; i >0 && pBuf!=NULL ;i--){ IX_OSAL_MBUF* pBufTemp; pBufTemp = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(pBuf); /* Freed MBUF Data Memory area*/ IX_OSAL_CACHE_DMA_FREE( (void *) (IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(pBuf)) ); /* Freed MBUF Struct Memory area*/ IX_OSAL_CACHE_DMA_FREE(pBuf); pBuf = pBufTemp; } #else IX_OSAL_CACHE_DMA_FREE (pool->mbufMemPtr); IX_OSAL_CACHE_DMA_FREE (pool->dataMemPtr); #endif } ixOsalBuffFreePools[pool->poolIdx / IX_OSAL_BUFF_FREE_BITS] &= ~(1 << (pool->poolIdx % IX_OSAL_BUFF_FREE_BITS)); ixOsalBuffPoolsInUse--; return IX_SUCCESS; }
IX_STATUS ixOsalSemaphoreGetValue (IxOsalSemaphore * sid, UINT32 * value) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "ixOsalSemaphoreGetValue(): Not supported \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; }
/** * @ingroup IxTimeSyncAccCodelet * * @fn ixTimeSyncAccCodeletPortConfigure ( IxEthAccPortId portId) * * @brief Setup Tx and Rx callbacks and MAC address * * @param * portId IxEthAccPortId [in] - port ID * * @return IX_STATUS * @li IX_SUCCESS - all function operations complete successfully * @li IX_FAIL - any operation fails */ PRIVATE IX_STATUS ixTimeSyncAccCodeletPortConfigure (IxEthAccPortId portId) { IxEthAccMacAddr npeMacAddr; if (IX_ETH_PORT_3 < portId) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPortConfigure: invalid port Id %d\n", portId, 0, 0, 0, 0, 0); return IX_FAIL; } /* setup TX callback */ if (IX_ETH_ACC_SUCCESS != ixEthAccPortTxDoneCallbackRegister (portId, ixTimeSyncAccCodeletTxDoneCB, portId)) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPortConfigure: Failed to register Tx callback for port %d\n", portId, 0, 0, 0, 0, 0); return IX_FAIL; } /* setup RX callback */ if (IX_ETH_ACC_SUCCESS != ixEthAccPortRxCallbackRegister (portId, ixTimeSyncAccCodeletDummyCB, portId)) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPortConfigure: Failed to register Rx callback for port %d\n", portId, 0, 0, 0, 0, 0); return IX_FAIL; } /* setup MAC address */ ixOsalMemCopy (npeMacAddr.macAddress, &ixTimeSyncAccCodeletNpeMacAddr[portId], IX_IEEE803_MAC_ADDRESS_SIZE); if (IX_ETH_ACC_SUCCESS != ixEthAccPortUnicastMacAddressSet(portId, &npeMacAddr)) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPortConfigure: failed to set the Unicast MAC Address of port %d\n", portId, 0, 0, 0, 0, 0); return IX_FAIL; } return IX_SUCCESS; } /* end of ixTimeSyncAccCodeletPortConfigure function */
/** * @ingroup IxTimeSyncAccCodelet * * @fn ixTimeSyncAccCodeletMbufAllocate () * * @brief Allocate memory for mBuf and its associated data buffer * * @return * @li IX_OSAL_MBUF * - successfully allocated memory for mBuf * @li NULL - fail */ PRIVATE IX_OSAL_MBUF *ixTimeSyncAccCodeletMbufAllocate () { IX_OSAL_MBUF *mBufPtr; UINT8 *dataPtr; /* Allocate cache-aligned memory for mbuf header */ mBufPtr = (IX_OSAL_MBUF *) IX_OSAL_CACHE_DMA_MALLOC (sizeof (IX_OSAL_MBUF)); if (NULL == mBufPtr) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletMbufAllocate: failed to allocate memory for mBuf\n", 0, 0, 0, 0, 0, 0); return NULL; } /* initialize mBuf */ ixOsalMemSet (mBufPtr, 0, sizeof (IX_OSAL_MBUF)); /* Allocate cache-aligned memory for mbuf data */ dataPtr = (UINT8 *) IX_OSAL_CACHE_DMA_MALLOC (IX_TIMESYNCACC_CODELET_UDP_FRAME_LEN); if (NULL == dataPtr) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletMbufAllocate: failed to allocate memory for mBuf's data buffer\n", 0, 0, 0, 0, 0, 0); return NULL; } /* initialize mBuf's data buffer */ ixOsalMemSet (dataPtr, 0, IX_TIMESYNCACC_CODELET_UDP_FRAME_LEN); /* Fill in mbuf header fields */ IX_OSAL_MBUF_MDATA (mBufPtr) = dataPtr; IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (mBufPtr) = (UINT32)dataPtr; IX_OSAL_MBUF_MLEN (mBufPtr) = IX_TIMESYNCACC_CODELET_UDP_FRAME_LEN; IX_OSAL_MBUF_ALLOCATED_BUFF_LEN (mBufPtr) = IX_TIMESYNCACC_CODELET_UDP_FRAME_LEN; IX_OSAL_MBUF_PKT_LEN (mBufPtr) = IX_TIMESYNCACC_CODELET_UDP_FRAME_LEN; return mBufPtr; } /* end of ixTimeSyncAccCodeletMbufAllocate function */