PRIVATE IX_STATUS ixAtmmTxDoneLoop (void* arg, void** retArgObj) { unsigned dummyPtr; IX_STATUS retval; while (!ixOsalThreadStopCheck()) { /* * Sleep for the timer duration */ ixOsalSleep (IX_ATMM_TX_DONE_PERIOD_MSECS); /* * Service Tx Done, process all the queue * but release the fast mutex to allow interrupts * running and service tx done when it is really needed. */ retval = ixAtmmTxDoneHandle (IX_ATMDACC_ALLPDUS, &dummyPtr); IX_OSAL_ENSURE(retval == IX_SUCCESS, "Call to ixAtmmTxDoneHandle() failed"); } ixOsalSleep (50); return IX_SUCCESS; }
PRIVATE IX_STATUS ixAtmmRxLoPriorityLoop (void* arg, void** ptrRetObj) { unsigned dummyPtr; IX_STATUS retval; while (!ixOsalThreadStopCheck()) { /* * Sleep for the timer duration */ ixOsalSleep (IX_ATMM_RX_LO_PRIORITY_PERIOD_MSECS); /* * Service Rx low priority queue, process all in Q */ retval = ixAtmdAccRxDispatch ( IX_ATM_RX_B, IX_ATMDACC_ALLPDUS, &dummyPtr); IX_OSAL_ENSURE(retval == IX_SUCCESS, "Call to ixAtmdAccRxDispatch() failed"); } ixOsalSleep (50); return IX_SUCCESS; }
/********************************************************************* * ixEthAccMiiWriteRtn - write a 16 bit value to a PHY */ IxEthAccStatus ixEthAccMiiWriteRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 value) { UINT32 mdioCommand; UINT32 regval; UINT16 readVal; UINT32 miiTimeout; if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) { return (IX_ETH_ACC_FAIL); } if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR) || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG)) { return (IX_ETH_ACC_FAIL); } /* ensure that a PHY is present at this address */ if(ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, &readVal) != IX_ETH_ACC_SUCCESS) { return (IX_ETH_ACC_FAIL); } ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL | phyAddr << IX_ETH_ACC_MII_ADDR_SHL ; mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value; ixEthAccMdioCmdWrite(mdioCommand); miiTimeout = ixEthAccMiiRetryCount; while(miiTimeout) { ixEthAccMdioCmdRead(®val); /*The "GO" bit is reset to 0 when the write completes*/ if((regval & IX_ETH_ACC_MII_GO) == 0x0) { break; } /* Sleep for a while */ ixOsalSleep(ixEthAccMiiAccessTimeout); miiTimeout--; } ixOsalMutexUnlock(&miiAccessLock); if(miiTimeout == 0) { return IX_ETH_ACC_FAIL; } return IX_ETH_ACC_SUCCESS; }
/* --------------------------------------------------- */ PRIVATE IX_STATUS ixOamTxAndRetry(IxAtmConnId connId, IX_OSAL_MBUF * mbufPtr, IxAtmdAccClpStatus clp, UINT32 numberOfCells) { IX_STATUS status = IX_FAIL; int retryCount = IX_OAM_TX_RETRY_COUNT_MAX; /* retry until the PDU is successfully submitted, or the submit fails, or the maximum number of retries is exceede. */ while(retryCount-- ) { status = ixAtmdAccTxVcPduSubmit (connId, mbufPtr, clp, numberOfCells); if( status != IX_ATMDACC_BUSY ) { return status; } ixOsalSleep(IX_OAM_TX_RETRY_DELAY); } return IX_FAIL; }
PRIVATE IX_STATUS ixOamCodeletOamPing(IxAtmLogicalPort port, UINT32 vpi, UINT32 vci, UINT32 pti, UINT32 numCells) { UINT32 sendCount = 0; if (!ixOamCodeletInitialized) { IX_OAM_CODELET_LOG_ERROR("Codelet not initialized\n"); return IX_FAIL; } if (port >= (IxAtmLogicalPort)ixOamCodeletNumPortsConfigured) { IX_OAM_CODELET_LOG_ERROR("Port not configured\n"); return IX_FAIL; } if (numCells == 0) { IX_OAM_CODELET_LOG_ERROR("numCells should be > 0\n"); return IX_FAIL; } /* Setup LB info */ lbVpi = vpi; lbVci = vci; lbPti = pti; lbPort = port; while (numCells--) { /* Notify user that a loopback cell is being sent */ IX_OAM_CODELET_LOG ("Sending loopback cell %u\n", sendCount++); /* Send the first cell */ if( ixOamParentLbCellTx (port, vpi, vci, pti) != IX_SUCCESS ) { IX_OAM_CODELET_LOG_ERROR("Failed to send parent loopback cell #%u",sendCount); return IX_FAIL; } /* * A message is displayed at the command shell if a correct loopback child cell has been received in * response to the sending of the parent cell. No message is displayed if no correct child cell * has been received */ /* Wait for 5 seconds for response, see ITU-610 */ ixOsalSleep (IX_OAM_ITU610_LB_TIMEOUT_PERIOD_MSECS); } return IX_SUCCESS; }
/** * @fn IxCryptoAccStatus ixCryptoPkeEauUnInit * @brief UnInitialize EAU (unbind interrupt) */ IxCryptoAccStatus ixCryptoPkeEauUninit (void) { UINT32 timer = 0; if (initDone) /* if (initialized) */ { /* Check if all request has finished */ while (pkeEauStats.totalReqCount != pkeEauStats.totalReqDoneCount) { /* Put the task into sleep mode and wait for the EAU to complete * all the operations */ ixOsalSleep(IX_CRYPTO_ACC_DELAY_IN_MS); /* Timer to avoid infinite lock */ timer++; if (IX_CRYPTO_ACC_TIMER_COUNT < timer ) { /* Log error message in debugging mode */ IX_CRYPTO_ACC_LOG ( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "EAU Request is not done!\n", 0, 0, 0, 0, 0, 0); return IX_CRYPTO_ACC_STATUS_FAIL; } /* End of if timer loop */ } /* end of while (pkeEauStats.totalReqCount != pkeEauStats.totalReqDoneCount) */ /* Unbind ISR */ if (IX_CRYPTO_ACC_STATUS_SUCCESS != IX_CRYPTO_ACC_IRQ_UNBIND (IX_OSAL_IXP400_EAU_DONE_IRQ_LVL)) { /* Log error message in debugging mode if unbind fail */ IX_CRYPTO_ACC_LOG ( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Unbind irq fail.\n", 0, 0, 0, 0, 0, 0); return IX_CRYPTO_ACC_STATUS_FAIL; } /* end of if (IX_CRYPTO_ACC_STATUS_SUCCESS != * IX_CRYPTO_ACC_IRQ_UNBIND (IX_OSAL_IXP400_EAU_DONE_IRQ_LVL)) */ initDone = FALSE; return IX_CRYPTO_ACC_STATUS_SUCCESS; } else /* not initialized */ { return IX_CRYPTO_ACC_STATUS_FAIL; }/* end of if (initDone) */ }/* end of ixCryptoPkeEauUnInit() function */
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 */
/* -------------------------------------------------------------- IxQMgrDispatcher task entry point. -------------------------------------------------------------- */ PRIVATE int ixAtmCodeletDispatchTask (void *arg, void **ptrRetObj) { /* This is an example of a task based dispatcher */ while (TRUE) { /* ATM Tx, Rx, TxDone queues */ (*dispatcherFunc) (IX_QMGR_QUELOW_GROUP); /* ATM RxFree queues */ (*dispatcherFunc) (IX_QMGR_QUEUPP_GROUP); ixOsalSleep(0); } }
IX_STATUS ixNpeMhSendMessageWithResponseSend ( IxNpeMhNpeId npeId, IxNpeMhMessage message, IxNpeMhMessageId solicitedMessageId, IxNpeMhCallback solicitedCallback, UINT32 maxSendRetries) { IX_STATUS status = IX_SUCCESS; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhSendMessageWithResponseSend\n"); /* update statistical info */ ixNpeMhSendStats[npeId].sendWithResponses++; /* sr: this sleep will call the receive routine (no interrupts used!!!) */ ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US); /* check if the NPE's inFIFO is full - if so return an error */ if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries)) { IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n"); return IX_FAIL; } /* save the solicited callback */ status = ixNpeMhSolicitedCbMgrCallbackSave ( npeId, solicitedMessageId, solicitedCallback); if (status != IX_SUCCESS) { IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n"); /* update statistical info */ ixNpeMhSendStats[npeId].callbackFulls++; return status; } /* write the message to the NPE's inFIFO */ status = ixNpeMhConfigInFifoWrite (npeId, message); IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhSendMessageWithResponseSend\n"); return status; }
void ixHssAccCodeletChannelisedServiceStop ( IxHssAccHssPort hssPortId) { IX_STATUS status; ClientInfo *pClientInfo = &clientInfo[hssPortId]; /****************/ /* STOP SERVICE */ /****************/ /* stop the Channelised Service for the client */ status = ixHssAccChanPortDisable (hssPortId); /* if there was any problem then update stats */ if (status != IX_SUCCESS) { stats[hssPortId].chan.portDisableFails++; return; } /**********************/ /* DISCONNECT SERVICE */ /**********************/ /* disconnect the Channelised Service for the client */ status = ixHssAccChanDisconnect (hssPortId); /* if there was any problem then update stats */ if (status != IX_SUCCESS) { stats[hssPortId].chan.disconnectFails++; return; } /***************/ /* STOP THREAD */ /***************/ /* wait for thread to finish processing messages */ while (pClientInfo->qTail != pClientInfo->qHead) { /* wait for 50ms */ ixOsalSleep (50); } }
/** * @ingroup IxTimeSyncAccCodelet * * @fn ixTimeSyncAccCodeletPTPMsgTransmitStop () * * @brief Stop PTP message transmission and destroy semaphore that is used in the * transmission. * * @return void */ PRIVATE void ixTimeSyncAccCodeletPTPMsgTransmitStop () { /* set PTP message transmission halt flag */ ixTimeSyncAccCodeletTxHalt = TRUE; /* wait for a while to let unfinished PTP message transmission to complete */ ixOsalSleep (IX_TIMESYNCACC_CODELET_PTP_MSG_XMIT_INTERVAL); if (NULL != ixTimeSyncAccCodeletSemId) { if (IX_SUCCESS != ixOsalSemaphoreDestroy (&ixTimeSyncAccCodeletSemId)) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletPTPMsgTransmitStop: failed to destroy semaphore\n", 0, 0, 0, 0, 0, 0); } ixTimeSyncAccCodeletSemId = NULL; } } /* end of ixTimeSyncAccCodeletPTPMsgTransmitStop function */
PUBLIC IX_STATUS ixAtmmPortDisable (IxAtmLogicalPort port) { IX_STATUS retval; UINT32 lockKey; /* ensure no interrupt is running (scheduling and transmission is done under interrupts) */ lockKey = ixOsalIrqLock(); IX_ATMM_PORT_MUTEX_TRY_LOCK(port); /* now, cell transmission is stopped */ ixOsalIrqUnlock(lockKey); /* tell the NPE to stop draining the TX queue */ retval = ixAtmdAccPortDisable(port); if (retval == IX_SUCCESS) { /* wait until a Disable is complete */ while (ixAtmdAccPortDisableComplete(port) == FALSE) { /* since TX done is processing the response, the time to wait is linked to the TxDone polling time */ ixOsalSleep(IX_ATMM_TX_DONE_PERIOD_MSECS/2 ); } } else if (retval == IX_ATMDACC_WARNING) { /* the port is already down */ retval = IX_SUCCESS; } else { retval = IX_FAIL; } IX_ATMM_PORT_MUTEX_UNLOCK(port); return retval; }
IX_STATUS ixEthAccCodeletLinkUpCheck(IxEthAccPortId portId) { IX_STATUS returnStatus = IX_SUCCESS; BOOL fullDuplex; BOOL linkUp; BOOL speed; BOOL autoneg; /* get the status */ ixEthMiiLinkStatus(ixEthAccCodeletPhyAddresses[portId], &linkUp, &speed, &fullDuplex, &autoneg); if (!linkUp) { unsigned int retry = 20; /* 20 retries */ printf("Wait for PHY %u to be ready ...\n", portId); while ((!linkUp) && (retry-- > 0)) { ixOsalSleep(100); /* 100 milliseconds */ /* get the status again */ ixEthMiiLinkStatus(ixEthAccCodeletPhyAddresses[portId], &linkUp, &speed, &fullDuplex, &autoneg); } if (!linkUp) { returnStatus = IX_FAIL; } } /* return fail if one of the links is not up */ return returnStatus; }
PRIVATE void ixEthAccCodeletDBMaintenanceTask (void* arg, void** ptrRetObj) { UINT32 count; ixEthAccCodeletDBMaintenanceTaskStopTrigger = FALSE; if (ixOsalMutexLock (&ixEthAccCodeletDBMaintenanceTaskRunning, IX_OSAL_WAIT_FOREVER) != IX_SUCCESS) { printf("DbLearning: Error starting Database Maintenance thread! Failed to lock mutex.\n"); return; } while (1) { /* * The Database maintenance function must be called at a period * of approximately IX_ETH_DB_MAINTENANCE_TIME seconds * regardless of whether learning is enabled or not. */ for (count = 0; count < IX_ETH_DB_MAINTENANCE_TIME; count++) { ixOsalSleep(1000); /* 1000 milliseconds */ if (ixEthAccCodeletDBMaintenanceTaskStopTrigger) { break; /* Exit the delay loop */ } } if (ixEthAccCodeletDBMaintenanceTaskStopTrigger) { break; /* Exit the thread loop */ } ixEthDBDatabaseMaintenance(); } ixOsalMutexUnlock (&ixEthAccCodeletDBMaintenanceTaskRunning); }
PRIVATE IX_STATUS ixEthAccCodeletLoop(void) { #ifdef __wince char str[16]; #elif defined (__linux) #endif printf(IX_ETHACC_CODELET_USER_INSTRUCTION); ixEthAccCodeletTrafficPollEnabled = TRUE; #ifdef __wince /* wait for the user to enter the sequence q<CR> */ do { gets(str); } while(str[0] != 'q'); #elif defined (__linux) /* wait for the user to stop the codelet */ ixEthAccCodelet_wait(); #elif defined (__vxworks) || defined (l4aos) /* wait for the user to enter the sequence <ESC><CR> */ int ch = 0; do { // ch = getchar(); ixOsalSleep(1100); } while (ch != 'q'); #else #error "Unsupported platform" #endif ixEthAccCodeletTrafficPollEnabled = FALSE; return (IX_SUCCESS); }
/********************************************************************* * ixEthAccMiiReadRtn - read a 16 bit value from a PHY */ IxEthAccStatus ixEthAccMiiReadRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 *value) { UINT32 mdioCommand; UINT32 regval; UINT32 miiTimeout; if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) { return (IX_ETH_ACC_FAIL); } if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR) || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG)) { return (IX_ETH_ACC_FAIL); } if (value == NULL) { return (IX_ETH_ACC_FAIL); } ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL | phyAddr << IX_ETH_ACC_MII_ADDR_SHL; mdioCommand |= IX_ETH_ACC_MII_GO; ixEthAccMdioCmdWrite(mdioCommand); miiTimeout = ixEthAccMiiRetryCount; while(miiTimeout) { ixEthAccMdioCmdRead(®val); if((regval & IX_ETH_ACC_MII_GO) == 0x0) { break; } /* Sleep for a while */ ixOsalSleep(ixEthAccMiiAccessTimeout); miiTimeout--; } if(miiTimeout == 0) { ixOsalMutexUnlock(&miiAccessLock); *value = 0xffff; return IX_ETH_ACC_FAIL; } ixEthAccMdioStatusRead(®val); if(regval & IX_ETH_ACC_MII_READ_FAIL) { ixOsalMutexUnlock(&miiAccessLock); *value = 0xffff; return IX_ETH_ACC_FAIL; } *value = regval & 0xffff; ixOsalMutexUnlock(&miiAccessLock); return IX_ETH_ACC_SUCCESS; }
/* * Function definition : ixDmaAccCodeletTestPerform() * See header file for documentation. */ IX_STATUS ixDmaAccCodeletTestPerform( UINT16 transferLength, IxDmaTransferMode transferMode, IxDmaAddressingMode addressingMode, IxDmaTransferWidth transferWidth) { UINT32 transferCounter; UINT32 counterTimeOut = 0; IX_STATUS retval; /* Initialise Source Address to ixDmaAccCodeletSrcBlock */ UINT32 sourceAddr = (UINT32) ixDmaAccCodeletSrcBlock; /* Initialise Destination Address to ixDmaAccCodeletDestBlock */ UINT32 destinationAddr = (UINT32) ixDmaAccCodeletDestBlock; /* Initialise Test Patterns */ ixDmaAccCodeletTestPatternReset(); printf ("\nTransferred %d times with the following parameters", PERFORMANCE_LOOP_NUM); printf ("\nSource Address : 0x%x", sourceAddr); printf ("\nDestination Address : 0x%x", destinationAddr); printf ("\nTransfer Length : %d", transferLength); printf ("\nTransfer Mode : %s", ixDmaAccCodeletMsgTM[transferMode]); printf ("\nAddressing Mode : %s", ixDmaAccCodeletMsgAM[addressingMode]); printf ("\nTransfer Width : %s", ixDmaAccCodeletMsgTW[transferWidth]); printf ("\n\n%d byte memory dump before transfer :", IX_DMA_CODELET_MEMDUMPSIZE ); /* Show memory dump before transfer */ ixDmaAccCodeletShow(); /* Do Dma transfer for PERFORMANCE_NUM_LOOP (i.e. 100 runs) for each different type of configuration */ for (transferCounter = 0; transferCounter < PERFORMANCE_LOOP_NUM; transferCounter++) { /* Initialise Test Patterns */ ixDmaAccCodeletTestPatternReset(); ixDmaAccCodeletLoopCount = transferCounter; ixDmaAccCodeletTimeStore.startTime[transferCounter] = ixOsalTimestampGet(); /* Perform Dma Transfer */ /* Callback function will update the status and CallBackReturn flag */ retval = ixDmaAccDmaTransfer( (IxDmaAccDmaCompleteCallback) ixDmaAccCodeletCallback, sourceAddr, destinationAddr, transferLength, transferMode, addressingMode, transferWidth ); /* Go into while loop if FIFO FULL happens */ while (IX_DMA_REQUEST_FIFO_FULL == retval) { printf ("\nFIFO is FULL. Going to sleep mode "); /*Delay in 1 MSecond before Dma Request Q recovers */ ixOsalSleep(IX_CLIENT_SLEEP_IN_MS); counterTimeOut++; if (IX_DMA_CODELET_MAX_TIME_OUT == counterTimeOut) { /* Stop the operation and return fail */ printf("\nTime out on FIFO full"); return IX_FAIL; } /* Retransmit after 1ms */ retval = ixDmaAccDmaTransfer( (IxDmaAccDmaCompleteCallback) ixDmaAccCodeletCallback, sourceAddr, destinationAddr, transferLength, transferMode, addressingMode, transferWidth ); } /* If retval is not successful returns failure */ if (IX_DMA_SUCCESS != retval) { printf("\nDma Transfer fail"); return IX_FAIL; } /* set to 0 used for callback return count time out */ counterTimeOut = 0; /* Wait for callback to return */ while (!ixDmaAccCodeletCallBackReturnFlag) { /*wait until current transfer complete */ ixOsalSleep(IX_CLIENT_SLEEP_IN_MS); counterTimeOut++; if (IX_DMA_CODELET_MAX_TIME_OUT == counterTimeOut) { /* Stop the operation and return fail */ printf("\nTime out on callback"); return IX_FAIL; } } /* set counter to 0 so that it will be used by the next iteration */ counterTimeOut = 0; /* When callback is returned, set flag to false */ ixDmaAccCodeletCallBackReturnFlag = FALSE; }/* End of for-loop for transfer counter*/ /* At the end of 100 runs and after callback returned successfully then do show here */ if (IX_SUCCESS == ixDmaAccCodeletCallBackStatus) { printf ("\n\n%d byte memory dump after transfer :", IX_DMA_CODELET_MEMDUMPSIZE ); /* Memory dump to show result of the current transfer */ ixDmaAccCodeletShow(); /* Print out the average time for that configuration */ ixDmaAccCodeletReportAverageTime(transferLength); } return IX_SUCCESS; }
/** * @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 */
PRIVATE void ixOamCellRxTask( void ) { IxOamITU610Cell *rxCell; UINT32 pti; UINT32 vci; UINT32 vpi; UINT32 oamRxHdr=0x0; IX_OSAL_MBUF *rxMbuf; int port; while(1) { for( port=0; port<ixOamCodeletNumPorts; port++ ) { if(!ixOamQueueEmptyQuery(&ixOamSwQueue[port])) { rxMbuf = ixOamMBufQueueGet(&ixOamSwQueue[port]); IX_OSAL_ASSERT( rxMbuf != NULL ); /* invalidate cache */ ixOamRxInvalidate( rxMbuf ); rxCell = (IxOamITU610Cell *)(IX_OSAL_MBUF_MDATA(rxMbuf)); /* Read the VCI & Payload Type */ IX_OAM_HEADER_GET(rxCell, oamRxHdr); vci = IX_OAM_VCI_GET(oamRxHdr); vpi = IX_OAM_VPI_GET(oamRxHdr); pti = IX_OAM_PTI_GET(oamRxHdr); /* Ensure access layer delivered a correct OAM cell */ IX_OSAL_ASSERT ((vci == IX_OAM_ITU610_F4_SEG_VCI) || (vci == IX_OAM_ITU610_F4_ETE_VCI) || (pti == IX_OAM_ITU610_F5_ETE_PTI) || (pti == IX_OAM_ITU610_F5_SEG_PTI)); /* Is it an Loopback cell ? */ if ( (IX_OAM_TYPE_AND_FUNC_GET(rxCell)) == IX_OAM_ITU610_TYPE_FAULT_MAN_LB ) { /* Is Parent Loopback Indication field in cell set? */ if ( (IX_OAM_LOOPBACK_INDICATION_GET(rxCell)) == IX_OAM_ITU610_LB_INDICATION_PARENT ) { ixOamParentLbCellRx (port, rxMbuf); } /* Otherwise child cell, i.e. response to loopback cell sent earlier */ else { ixOamChildLbCellRx(port, rxMbuf); } } else { unsupportedOamRxCount[port]++; /* free the buffer */ ixAtmUtilsMbufFree (rxMbuf); } } } /* share the CPU */ ixOsalSleep(IX_OAM_RX_QUEUE_POLL_INTERVAL); } }
/** * @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; }
/****************************************************************** * * Reset the PHY at the specified address */ PUBLIC IX_STATUS ixEthMiiPhyReset(UINT32 phyAddr) { UINT32 timeout; UINT16 regval; if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) && (ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID)) { if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) || (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) || (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973_PHY_ID) || (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973A3_PHY_ID) || (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID) ) { /* use the control register to reset the phy */ ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, IX_ETH_MII_CR_RESET); /* poll until the reset bit is cleared */ timeout = 0; do { ixOsalSleep (IX_ETH_MII_RESET_POLL_MS); /* read the control register and check for timeout */ ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_CTRL_REG, ®val); if ((regval & IX_ETH_MII_CR_RESET) == 0) { /* timeout bit is self-cleared */ break; } timeout += IX_ETH_MII_RESET_POLL_MS; } while (timeout < IX_ETH_MII_RESET_DELAY_MS); /* check for timeout */ if (timeout >= IX_ETH_MII_RESET_DELAY_MS) { ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, IX_ETH_MII_CR_NORM_EN); return IX_FAIL; } return IX_SUCCESS; } /* end of if(ixEthMiiPhyId) */ else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID) { /* reset bit is reserved, just reset the control register */ ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, IX_ETH_MII_CR_NORM_EN); return IX_SUCCESS; } else { /* unknown PHY, set the control register reset bit, * wait 2 s. and clear the control register. */ ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, IX_ETH_MII_CR_RESET); ixOsalSleep (IX_ETH_MII_RESET_DELAY_MS); ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, IX_ETH_MII_CR_NORM_EN); return IX_SUCCESS; } /* end of if-else(ixEthMiiPhyId) */ } /* end of if(phyAddr) */ return IX_FAIL; }
/** * @fn void ixEthAccCodeletStatsPollTask * * This task polls the Codelet Stats and displays the rate of Rx and * Tx packets per second. * */ PRIVATE void ixEthAccCodeletStatsPollTask(void* arg, void** ptrRetObj) { int portNo = 0; static char stillRunning[] = "|/-\\"; static int stillRunningIndex = 0; static char displayString[20 + (21 * IX_ETHACC_CODELET_MAX_PORT)]; static char *stringPtr; static UINT32 busTimestampEnd = 0; static UINT32 busTimestampStart = 0; static UINT32 pTimeCycles = 0; static UINT64 rxCount = 0; static UINT64 txCount = 0; static UINT64 pTimeUsecs = 0; ixEthAccCodeletStatsPollTaskStop = FALSE; if (ixOsalMutexLock (&ixEthAccCodeletStatsPollTaskRunning, IX_OSAL_WAIT_FOREVER) != IX_SUCCESS) { printf("CodeletMain: Error starting Stats thread! Failed to lock mutex.\n"); return; } while (1) { while (ixEthAccCodeletTrafficPollEnabled == FALSE) { /* Sleep 1 sec */ ixOsalSleep(1000); if (ixEthAccCodeletStatsPollTaskStop) { break; /* Exit the thread */ } } if (ixEthAccCodeletStatsPollTaskStop) { break; /* Exit the thread */ } printf("\n"); #ifdef __wince printf("\r"); #endif for(portNo=0; portNo<IX_ETHACC_CODELET_MAX_PORT; portNo++) { printf("Port%d Rates: |",portNo); } printf("\n"); #ifdef __wince printf("\r"); #endif for(portNo=0; portNo<IX_ETHACC_CODELET_MAX_PORT; portNo++) { printf("====================="); } printf("=\n"); #ifdef __wince printf("\r"); #endif /* reset the stats */ for(portNo=0; portNo<IX_ETHACC_CODELET_MAX_PORT; portNo++) { ixEthAccCodeletStats[portNo].rxCount=0; ixEthAccCodeletStats[portNo].txCount=0; } while (ixEthAccCodeletTrafficPollEnabled) { busTimestampStart = ixOsalTimestampGet(); /* Sleep approximatively 1 sec */ ixOsalSleep(1000); /* check if the task should stop */ if (ixEthAccCodeletStatsPollTaskStop) { break; /* Exit the thread */ } if (ixEthAccCodeletTrafficPollEnabled) { /* \r : reset print curser to beginning of line */ stringPtr = displayString; *stringPtr++ = '\r'; for(portNo=0; portNo<IX_ETHACC_CODELET_MAX_PORT; portNo++) { /* get a snapshot */ busTimestampEnd = ixOsalTimestampGet(); rxCount = ixEthAccCodeletStats[portNo].rxCount; txCount = ixEthAccCodeletStats[portNo].txCount; /* Got stats, now clear counters */ ixEthAccCodeletStats[portNo].rxCount=0; ixEthAccCodeletStats[portNo].txCount=0; /* get the measurement interval using a unsigned * subtraction in order to handle wrap-around. The time unit * is in APB bus cycles. */ pTimeCycles = busTimestampEnd - busTimestampStart; /* convert the time in APB bus cycles to microseconds * * multiplications are done before divisions and * will not overflow the UINT64. */ pTimeUsecs = (UINT64)pTimeCycles; pTimeUsecs = IX_ETHACC_CODELET_MULDIV(pTimeUsecs, IX_ETHACC_CODELET_PCLOCK_DIVIDER, IX_ETHACC_CODELET_XCLOCK_FREQ); if (!pTimeUsecs) { /* time may be 0 as the result of the previous operation * In this case (very unlikely to occur), * just skip the remaining of this loop. * The display will not be updated before the next * loop. */ continue; } /* convert from the packet count to a rate in pkts per second * * rate = pkts * usecsPerSec / timeUsec * * multiplications are done before divisions and * will not overflow the UINT64. */ rxCount = IX_ETHACC_CODELET_MULDIV(rxCount, IX_ETHACC_CODELET_USEC_PER_SEC, pTimeUsecs); txCount = IX_ETHACC_CODELET_MULDIV(txCount, IX_ETHACC_CODELET_USEC_PER_SEC, pTimeUsecs); /* print stats */ stringPtr += sprintf(stringPtr, "Rx:%6u Tx:%6u |", (unsigned)rxCount, (unsigned)txCount); } *stringPtr++ = stillRunning[stillRunningIndex++ & 3]; *stringPtr = 0; printf("%s", displayString); } } printf("\n"); #ifdef __wince printf("\r"); #endif } ixOsalMutexUnlock (&ixEthAccCodeletStatsPollTaskRunning); }
/* * Function definition: ixEthAccCodeletDBLearningRun() * * Run ethDB demo for all ports passed as parameters */ IX_STATUS ixEthAccCodeletDBLearningRun(BOOL validPorts[]) { IxEthAccPortId portId; IxEthDBPortId portPtr; IxEthDBMacAddr staticMacAddress[IX_ETHACC_CODELET_MAX_PORT] = {{{0,1,2,3,4,5}}, {{6,7,8,9,0,1}}}; IxEthDBMacAddr dynamMacAddress[IX_ETHACC_CODELET_MAX_PORT] = {{{0xa,0xb,0xc,0xd,0xe,0xf}}, {{0x0,0xb,0x3,0xc,0x4,0xd}}}; if (ixEthAccCodeletDBMaintenanceStart() != IX_SUCCESS) { printf("DbLearning: Error spawning DB maintenance task\n"); return (IX_FAIL); } /* configure all existing ports */ for (portId = 0; portId < IX_ETHACC_CODELET_MAX_PORT; portId++) { if (validPorts[portId]) { /* Configure the port */ printf("Configuring the port...\n"); if (ixEthAccCodeletPortConfigure(portId, ixEthAccCodeletMemPoolFreeRxCB, (IxEthAccPortMultiBufferRxCallback) NULL, ixEthAccCodeletMemPoolFreeTxCB, portId) != IX_ETH_ACC_SUCCESS) { printf("DbLearning: Failed to configure the port %u\n", (UINT32)portId); return IX_FAIL; } /* Enable the port */ printf("Enabling the port...\n"); if(ixEthAccPortEnable(portId) != IX_ETH_ACC_SUCCESS) { printf("DbLearning: Error enabling port %u\n", (UINT32)portId); return (IX_FAIL); } /* Add some static entries */ printf("Adding static entries...\n"); if (ixEthDBFilteringStaticEntryProvision(portId, &staticMacAddress[portId]) != IX_ETH_DB_SUCCESS) { printf("DbLearning: Failed to add static MAC to port %u\n", (UINT32)portId); return (IX_FAIL); } ixOsalSleep(100); /* Verify that the address has successfully been added */ if (ixEthDBFilteringDatabaseSearch(&portPtr, &staticMacAddress[portId]) == IX_ETH_DB_NO_SUCH_ADDR) { printf("DbLearning: Static MAC address not found in Database\n"); return (IX_FAIL); } /* Add some dynamic entries */ printf("Adding dynamic entries...\n"); if (ixEthDBFilteringDynamicEntryProvision(portId, &dynamMacAddress[portId]) != IX_ETH_DB_SUCCESS) { printf("DbLearning: Failed to add dynamic MAC to port %u\n", (UINT32)portId); } printf("Enabling aging...\n"); if (ixEthDBPortAgingEnable(portId) != IX_ETH_DB_SUCCESS) { printf("DbLearning: Failed to enable aging for port %u\n", (UINT32)portId); return (IX_FAIL); } } } ixEthDBFilteringDatabaseShowAll(); /* Wait 4 minutes over aging time (for safety) and verify that the * dynamic entries have been removed */ printf("Aging entries.\nWaiting for %d minutes...\n", IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60 + 3); ixOsalSleep((IX_ETH_DB_LEARNING_ENTRY_AGE_TIME + 180) * 1000); ixEthDBFilteringDatabaseShowAll(); for (portId = 0; portId < IX_ETHACC_CODELET_MAX_PORT; portId++) { if (validPorts[portId]) { if(ixEthDBFilteringEntryDelete(&staticMacAddress[portId]) != IX_ETH_DB_SUCCESS) { printf("DbLearning: Failed to remove static MAC on port %u\n", (UINT32)portId); } /* Disable ports */ if(ixEthAccPortDisable(portId) != IX_ETH_ACC_SUCCESS) { printf("DbLearning: Error disabling port %u\n", (UINT32)portId); return (IX_FAIL); } } } /* wait for pending traffic to be completely received */ if (ixEthAccCodeletRecoverBuffers() != IX_SUCCESS) { printf("Warning : Not all buffers are accounted for!\n"); } return (IX_SUCCESS); }