📄 ixatmmdatapath.c
字号:
* Setup notification for Tx Q low. * Notify when 0 enties in Q, i.e. Q is EMPTY. */ retval = ixAtmdAccPortTxCallbackRegister (port, 0, ixAtmmTxLowHandle); } if (retval == IX_SUCCESS) { /* * Initialize BUSY fast mutex for this port, * the mutex will be free, i.e. the port is not BUSY */ retval = ixOsalFastMutexInit (&ixAtmmTxBusyFastMutex[port]); } if (retval == IX_SUCCESS) { /* * Initialize PORT fast mutex for this port, * the mutex will be UP */ retval = ixOsalFastMutexInit (&ixAtmmPortFastMutex[port]); if (retval == IX_SUCCESS) { retval = IX_ATMM_PORT_MUTEX_TRY_LOCK(port); } } if (retval == IX_SUCCESS) { ixAtmmTxSchedulingInitDone[port] = TRUE; } else { retval = IX_FAIL; } return retval; }/* Private function for uninitialising the Tx Scheduling */PRIVATE IX_STATUSixAtmmTxSchedulingUninit (IxAtmLogicalPort port){ IX_STATUS retval = IX_SUCCESS; if (!ixAtmmTxSchedulingInitDone[port]) { retval = IX_FAIL; } /* * Uninitialize PORT fast mutex for this port, * */ if (IX_SUCCESS == retval) { retval = ixOsalFastMutexDestroy (&ixAtmmPortFastMutex[port]); } /* * Uninitialize BUSY fast mutex for this port, * */ if (IX_SUCCESS == retval) { retval = ixOsalFastMutexDestroy (&ixAtmmTxBusyFastMutex[port]); } ixAtmdAccPortTxCallbackUnregister (port); /* Put Atmm out of scheduling mode, this has to unregister the Atmm callbacks */ if (IX_SUCCESS == retval) { retval = ixAtmdAccPortTxScheduledModeDisable (port); } if (IX_SUCCESS == retval) { /* Set the corresponding port flag to FALSE */ ixAtmmTxSchedulingInitDone[port] = FALSE; } else { retval = IX_FAIL; } return retval;}PRIVATE voidixAtmmVcQueueClear (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId){ IX_STATUS retval; UINT32 lockKey; lockKey = ixOsalIrqLock(); retval = ixAtmSchVcQueueClear (port, vcId); ixOsalIrqUnlock (lockKey); IX_OSAL_ENSURE(retval == IX_SUCCESS, "Call to ixAtmSchVcQueueClear() failed");}PRIVATE IX_STATUSixAtmmVcDemandUpdate (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, unsigned numberOfCells){ IX_STATUS retval = IX_FAIL; IxAtmScheduleTable *retTable; UINT32 lockKey; /* * N.B. Running from a task or interrupt level. * From the task level we could be interrupted * so need to protect VcQueueUpdate, SchTableUpdate * and PortTxProcess */ lockKey = ixOsalIrqLock(); /* * If we can get the PORT fast mutex it means the port was * UP so can initiate transmission. */ if (IX_ATMM_PORT_MUTEX_TRY_LOCK(port) == IX_SUCCESS) { /* * Inform Scheduler of the demand * N.B. This is data path so IxAtmSch will validate parameters * rather than do this twice. */ retval = ixAtmSchVcQueueUpdate (port, vcId, numberOfCells); if( retval == IX_SUCCESS ) { /* * If we can get the BUSY fast mutex it means the port was * IDLE so we need to initiate transmission. */ if (IX_ATMM_TX_MUTEX_TRY_LOCK(port) == IX_SUCCESS) { /* * Build a new schedule table, N.B. system was idle so can potentially * generate a table with ixAtmmTxQSize cells */ retval = ixAtmSchTableUpdate (port, ixAtmmTxQSize[port], &retTable); /* * VcQueueUpdate above placed cells in the scheduler * so the tableUpdate should succeed */ IX_OSAL_ASSERT(retval == IX_SUCCESS); /* * Tell Atmd to send the cells in the schedule table. */ retval = ixAtmdAccPortTxProcess (port, retTable); if (retval != IX_SUCCESS) { retval = IX_FAIL; } } } IX_ATMM_PORT_MUTEX_UNLOCK(port); } ixOsalIrqUnlock (lockKey); return retval;}PRIVATE voidixAtmmTxLowHandle (IxAtmLogicalPort port, unsigned maxTxCells){ IxAtmScheduleTable *retTable; IX_STATUS retval; UINT32 lockKey; /* * If we can get the PORT fast mutex it means the port was * UP so can initiate transmission. */ if (IX_ATMM_PORT_MUTEX_TRY_LOCK(port) == IX_SUCCESS) { lockKey = ixOsalIrqLock(); /* * Build a new schedule table * N.B. This is data path so IxAtmSch will validate parameters * rather than do this twice. */ retval = ixAtmSchTableUpdate (port, maxTxCells, &retTable); if (retval == IX_SUCCESS) { /* * Tell Atmd to send the cells in the schedule table. */ retval = ixAtmdAccPortTxProcess (port, retTable); } else { /* * Only other valid retval is QUEUE_EMPTY */ IX_OSAL_ASSERT(retval == IX_ATMSCH_RET_QUEUE_EMPTY); /* * The schedule table is empty so the port has gone * IDLE. Free the BUSY mutex. */ IX_ATMM_TX_MUTEX_UNLOCK(port); } ixOsalIrqUnlock(lockKey); IX_ATMM_PORT_MUTEX_UNLOCK(port); }}PRIVATE IX_STATUSixAtmmRxHiPriorityInit (void){ IX_STATUS retval = IX_SUCCESS; /* Initialization done in first call to Init, * subsequent calls do nothing */ if (!ixAtmmRxHiPriorityInitDone) { /* * Hook Rx notification to Atmd rx process perform * this will notify us whenever there is data available. */ retval = ixAtmdAccRxDispatcherRegister (IX_ATM_RX_A, ixAtmdAccRxDispatch); if (retval == IX_SUCCESS) { ixAtmmRxHiPriorityInitDone = TRUE; } } return retval;}/* Function to unregister the Rx Hi priority dispacther */PRIVATE IX_STATUSixAtmmRxHiPriorityUninit (void){ IX_STATUS retval = IX_SUCCESS; if (ixAtmmRxHiPriorityInitDone) { /* If InitDone Unregister the Rx Dispacther */ retval = ixAtmdAccRxDispatcherUnregister (IX_ATM_RX_A); if (IX_SUCCESS == retval) { /* Reset the flag to FALSE on completing unintialisation */ ixAtmmRxHiPriorityInitDone = FALSE; } } return retval;}PRIVATE IX_STATUSixAtmmRxLoPriorityInit (void){ IxOsalThreadAttr ixAtmmRxLoPriorityThreadAttr; IX_STATUS retval = IX_SUCCESS; IX_STATUS retStatus; char *threadName = "Atmm Rx Low Priority Thread"; /* Initialization done in first call to Init, * subsequent calls do nothing */ if (!ixAtmmRxLoPriorityInitDone) { /* * Rx Low priority queue will be processed from * a timer. */ ixAtmmRxLoPriorityThreadAttr.name = threadName; ixAtmmRxLoPriorityThreadAttr.stackSize = 0; ixAtmmRxLoPriorityThreadAttr.priority = IX_ATMM_THREAD_PRI_HIGH; if ((retStatus = ixOsalThreadCreate( &ixAtmmTaskIds.rxLoPriorityId, &ixAtmmRxLoPriorityThreadAttr, (IxOsalVoidFnVoidPtr) ixAtmmRxLoPriorityLoop, NULL)) == IX_SUCCESS ) { /* start the thread */ ixAtmmRxLoPriorityInitDone = TRUE; retStatus |= ixOsalThreadStart(&ixAtmmTaskIds.rxLoPriorityId); } if (IX_SUCCESS != retStatus) { ixAtmmRxLoPriorityInitDone = FALSE; retval = IX_FAIL; } } return retval;}/* Function to unregister the Rx Low priority dispacther */PRIVATE IX_STATUSixAtmmRxLoPriorityUninit (void){ IX_STATUS retval = IX_SUCCESS; IX_STATUS retStatus; /* If Initialisation done continue */ if (ixAtmmRxLoPriorityInitDone) { /* Kill the RxLoPriority Thread */ retStatus = ixOsalThreadKill(&ixAtmmTaskIds.rxLoPriorityId); if (IX_SUCCESS != retStatus) { retval = IX_FAIL; } else { /* Make the init done flag FALSE */ ixAtmmRxLoPriorityInitDone = FALSE; retval = IX_SUCCESS; } } else { retval = IX_FAIL; } return retval;}PRIVATE IX_STATUSixAtmmTxDoneInit (void){ IxOsalThreadAttr ixAtmmTxDoneThreadAttr; IX_STATUS retval = IX_SUCCESS; IX_STATUS retStatus; unsigned qSize; char *threadName = "Atmm Tx Done Thread"; /* Initialization done in first call to Init, * subsequent calls do nothing */ if (!ixAtmmTxDoneInitDone) { /* * Get depth of TxDone Q */ retval = ixAtmdAccTxDoneQueueSizeQuery (&qSize); if (retval == IX_SUCCESS) { /* * Hook Tx Done notification to done handler, * threshold is set to half of q size */ retval = ixAtmdAccTxDoneDispatcherRegister ( qSize/2, ixAtmmTxDoneHandle); } if (retval == IX_SUCCESS) { /* * Setup timer to handle disconnect scenario * during idle traffic */ ixAtmmTxDoneThreadAttr.name = threadName; ixAtmmTxDoneThreadAttr.stackSize = 0; ixAtmmTxDoneThreadAttr.priority = IX_ATMM_THREAD_PRI_HIGH; if ((retStatus = ixOsalThreadCreate( &ixAtmmTaskIds.txDoneId, &ixAtmmTxDoneThreadAttr, (IxOsalVoidFnVoidPtr) ixAtmmTxDoneLoop, NULL)) == IX_SUCCESS ) { /* start the thread */ ixAtmmTxDoneInitDone = TRUE; retStatus |= ixOsalThreadStart(&ixAtmmTaskIds.txDoneId); } if (IX_SUCCESS != retStatus) { ixAtmmTxDoneInitDone = FALSE; retval = IX_FAIL; } } } return retval;}PRIVATE IX_STATUSixAtmmTxDoneUninit (void){ IX_STATUS retval = IX_SUCCESS; IX_STATUS retStatus; if (ixAtmmTxDoneInitDone) { /* Kill the thread for TxDone */ retStatus = ixOsalThreadKill(&ixAtmmTaskIds.txDoneId); if (IX_SUCCESS == retStatus) { ixAtmdAccTxDoneDispatcherUnregister (); } /* Reset the flag to FALSE on finishing uninitialisation */ ixAtmmTxDoneInitDone = FALSE; } return retval;}PRIVATE IX_STATUSixAtmmTxDoneHandle (unsigned numOfPdusToProcess, unsigned *reservedPtr){ IX_STATUS retval = IX_SUCCESS; UINT32 lockKey; lockKey = ixOsalIrqLock(); /* Call the Atmd Tx Done API */ retval = ixAtmdAccTxDoneDispatch (numOfPdusToProcess, reservedPtr); ixOsalIrqUnlock(lockKey); if (retval != IX_SUCCESS) { retval = IX_FAIL; } return retval;}PRIVATE IX_STATUS ixAtmmVcIdGet (IxAtmLogicalPort port, unsigned vpi, unsigned vci, IxAtmConnId connId, IxAtmSchedulerVcId *vcId){ IX_STATUS retval = IX_SUCCESS; IxAtmmVc vcDesc; /* Callback should be registered before calling this function */ if (vcQueryCallback == NULL) { retval = IX_FAIL; } if (retval == IX_SUCCESS) { /* * Call the registered VC query callback */ retval = vcQueryCallback (port, vpi, vci, IX_ATMM_VC_DIRECTION_TX, vcId, &vcDesc); } if (retval == IX_SUCCESS) { /* * Now inform AtmSch of the user connId */ retval = ixAtmSchVcConnIdSet ( port, *vcId, connId); if (retval != IX_SUCCESS) { retval = IX_FAIL; } } return retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -