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 */
/* * 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 void ixOsalSleep (UINT32 milliseconds) { if (milliseconds != 0) { #if 1 /* * sr: We poll while we wait because interrupts are off in U-Boot * and CSR expects messages, etc to be dispatched while sleeping. */ int i; IxQMgrDispatcherFuncPtr qDispatcherFunc; ixQMgrDispatcherLoopGet(&qDispatcherFunc); while (milliseconds--) { for (i = 1; i <= 2; i++) ixNpeMhMessagesReceive(i); (*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP); udelay(1000); } #endif } }
/* -------------------------------------------------------------- Initialise system components used by the Atm Codelet. -------------------------------------------------------------- */ PUBLIC IX_STATUS ixAtmCodeletSystemInit (UINT32 numPorts, IxAtmCodeletMode mode) { IX_STATUS retval = IX_SUCCESS; #if IX_UTOPIAMODE == 1 IxAtmmPhyMode phyMode = IX_ATMM_SPHY_MODE; #else IxAtmmPhyMode phyMode = IX_ATMM_MPHY_MODE; #endif IxOsalThread dispatchtid; IxOsalThreadAttr threadAttr; char *pThreadName = "QMgr Dispatcher"; #ifdef __vxworks if (endFindByName ("ixe", 0) != NULL) { IX_ATMCODELET_LOG ("FAIL : Driver ixe0 detected\n"); printf("FAIL : Driver ixe0 detected\n"); return IX_FAIL; } if (endFindByName ("ixe", 1) != NULL) { IX_ATMCODELET_LOG ("FAIL : Driver ixe1 detected\\n"); printf("FAIL : Driver ixe1 detected\n"); return IX_FAIL; } #endif /**************** System initialisation ****************/ /* * The IxQMgr component provides interfaces for configuring and accessing the IXP4XX * AQM hardware queues used to facilitate communication of data between the NPEs and * the xscale. IxAtmdAcc configures these queues. The IxQMgr component provides a * dispatcher that will call registered callback functions will specified queue events * occur. */ IX_ATMCODELET_COMP_INIT(ixQMgrInit()); ixQMgrDispatcherLoopGet(&dispatcherFunc); /* This next section sets up how the IxQMgrDispatcher is called. * For the purposes of demonstration under vxWorks the IxQMgrDispatcher * is polled, and under Linux intterrupts are used. * This offers the best performance respectively. */ if (IX_ATMCODELET_USE_QMGR_INT) { /* Running IxQMgrDispatcher from interrupt level */ /* * Bind the IxQMgr dispatcher to interrupt. The IX_QMGR_QUELOW_GROUP group * of queues concern ATM Transmit , Receive, Transmit Done queues */ retval = ixOsalIrqBind(IX_OSAL_IXP400_QM1_IRQ_LVL, (IxOsalVoidFnVoidPtr)(dispatcherFunc), (void *)IX_QMGR_QUELOW_GROUP); if (IX_SUCCESS != retval) { IX_ATMCODELET_LOG ("Failed to bind to QM1 interrupt\n"); return IX_FAIL; } /* * Bind the IxQMgr dispatcher to interrupt. The IX_QMGR_QUELOW_GROUP group * of queues concern ATM Receive Free queues. */ retval = ixOsalIrqBind(IX_OSAL_IXP400_QM2_IRQ_LVL, (IxOsalVoidFnVoidPtr)(dispatcherFunc), (void *)IX_QMGR_QUEUPP_GROUP); if (IX_SUCCESS != retval) { IX_ATMCODELET_LOG ("Failed to bind to QM2 interrupt\n"); return IX_FAIL; } } else /* Running IxQMgrDispatcher from task level */ { threadAttr.name = pThreadName; threadAttr.stackSize = IX_ATMCODELET_QMGR_DISPATCHER_THREAD_STACK_SIZE; threadAttr.priority = IX_ATMCODELET_QMGR_DISPATCHER_PRIORITY; if (ixOsalThreadCreate(&dispatchtid, &threadAttr, (IxOsalVoidFnVoidPtr)ixAtmCodeletDispatchTask, NULL) != IX_SUCCESS) { IX_ATMCODELET_LOG ("Error spawning dispatch task\n"); return IX_FAIL; } if(IX_SUCCESS != ixOsalThreadStart(&dispatchtid)) { IX_ATMCODELET_LOG ("Error starting dispatch task\n"); return IX_FAIL; } } /* Initialise IxNpeMh */ IX_ATMCODELET_COMP_INIT(ixNpeMhInitialize (IX_NPEMH_NPEINTERRUPTS_YES)); /* Download NPE image */ retval = ixAtmUtilsAtmImageDownload (numPorts, &phyMode); if (retval != IX_SUCCESS) { IX_ATMCODELET_LOG ("NPE download failed\n"); return IX_FAIL; } ixAtmCodeletMode = mode; return IX_SUCCESS; }
IX_STATUS ixEthAccCodeletDispatcherStart(BOOL useInterrupt) { IxOsalThread qDispatchThread; IxOsalThreadAttr threadAttr; threadAttr.name = "Codelet Q Dispatcher"; threadAttr.stackSize = 32 * 1024; /* 32kbytes */ threadAttr.priority = IX_ETHACC_CODELET_QMR_PRIORITY; if (!ixEthAccCodeletDispatcherInitialized) { /* this should be initialized once */ ixQMgrDispatcherLoopGet(&ixEthAccCodeletDispatcherFunc); ixOsalMutexInit (&ixEthAccCodeletDispatcherPollRunning); ixEthAccCodeletDispatcherPollStopTrigger = TRUE; ixEthAccCodeletDispatcherInitialized = TRUE; } if(useInterrupt) /* Interrupt mode */ { /* * Hook the QM QLOW dispatcher to the interrupt controller. */ if (ixOsalIrqBind(IX_ETH_CODELET_QMGR_IRQ, (IxOsalVoidFnVoidPtr)(ixEthAccCodeletDispatcherFunc), (void *)IX_QMGR_QUELOW_GROUP) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDispatcherPollRunning); printf("Dispatcher: Failed to bind to QM1 interrupt\n"); return (IX_FAIL); } } else { if (ixEthAccCodeletDispatcherPollStopTrigger) { /* Polled mode based on a task running a loop */ if (ixOsalThreadCreate(&qDispatchThread, &threadAttr, (IxOsalVoidFnVoidPtr) ixEthAccCodeletDispatcherPoll, NULL) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDispatcherPollRunning); printf("Dispatcher: Error spawning Q Dispatcher task\n"); return (IX_FAIL); } /* Start the thread */ if (ixOsalThreadStart(&qDispatchThread) != IX_SUCCESS) { ixOsalMutexDestroy(&ixEthAccCodeletDispatcherPollRunning); printf("Dispatcher: Error failed to start the Q Dispatcher thread\n"); return IX_FAIL; } } } return (IX_SUCCESS); }