📄 aal2txcp.c
字号:
/****************************************************************************** Copyright (c) 1998, 1999, 2000, 2001, 2002 C-Port Corporation, a Motorola Company* All Rights Reserved** The information contained in this file is C-Port Corporation confidential * and proprietary. Any reproduction, use or disclosure, in whole or in part, * of this program, including any attempt to obtain a human-readable version * of this program, without the express, prior written consent of C-Port* Corporation or Motorola Incorporated is strictly prohibited. *****************************************************************************//* Uncomment the following define for debug prints *//* #define AAL2_TX_DEBUG *//**************************** Header Files ***********************************/#include <dcpKernelSvcs.h>#include <dcpBufferSvcs.h>#include <dcpPduSvcs.h>#include <dcpTableSvcs.h>#include <dcpQueueSvcs.h>#include <bsBuffer.h>#include <atm.h>#include <aal2Desc.h>#include <atmCellDesc.h>#include <aal2.h>#include <aal2Rx.h>#include <aal2Tx.h>#include <aal2Init.h>#include <rcSdpAal2TxApiIf.h>#include <systemServicesLocal.h>/* Invalid VcIndex for Aal2 Switch Application */#define INVALID_VC_ID 0xFFFF/**************************** Global Variables *******************************/extern PDU ALIGNED64 rxTempPdu[MAX_SCOPES];extern PDU ALIGNED64 txTempPdu[MAX_SCOPES];extern QsMessage ALIGNED64 cellDescMsg;extern CellDescriptor *cellDescPtr;extern BsPoolId poolId;extern QsQueueId baseQueueId;extern KsContext aal2HdlrContext;extern KsContext aal2FwdrContext;AAL2_TX_CONTEXT *pAal2TxContext = NULL;int32u gAal2TxCpId = 0;Aal2CpsDesc *CpsDesc = NULL;XpInQueueDesc *XpQueueDesc = NULL;CellDescriptor *CellDesc = NULL;TimeoutDesc *TimeoutDescriptor = NULL;QsQueueId gXpBaseQId = 0;#ifndef SIM#define AAL2_STATISTICS#endif#ifdef AAL2_STATISTICSextern int32u txCells;extern int32u txAal2Pdus;extern int32u aal2EnqueueFail;#endifextern Boolean payloadEnqueue;extern BsBufHandle lastBufferEnqueued;/**************************** Function Prototypes ****************************/int32u aal2TxHdlr (void* arg);int32u aal2TxFwdr (void* arg);inline void EnqueueCellDescriptor (BsBufHandle AtmSduBufHandle, int16u AtmSduCount, int16u VcIndex);extern int32u aal2CpQmuIrqHandler(void *);/****************************************************************************** * Function : EnqueueCellDescriptor * * Description : Prepares and en-queues the cell descriptor to the destination * queue. * * Parameters : AtmSduBufHandle: Buffer handle for cell payload, AtmSduCount: * Count of bytes in ATM SDU, VcIndex: VC index for the cell. * * Returns : None. * * Traceability : None. * ******************************************************************************/inline void EnqueueCellDescriptor (BsBufHandle AtmSduBufHandle, int16u AtmSduCount, int16u VcIndex){ cellDescPtr->Bh = AtmSduBufHandle; cellDescPtr->VcIndex = VcIndex; cellDescPtr->CellHeader.word = pAal2TxContext->Aal2TxDmemTable[VcIndex & DMEM_TABLE_INDEX_MASK].atmEgressKey; /* Other fields of the cell descriptor are not known to AAL2Tx. ATM Tx/QoS * has to find out those fields. No need to set any thing here. */ lastBufferEnqueued = AtmSduBufHandle; payloadEnqueue = TRUE; /* En-queue the cell descriptor */ qsMessageSend(pAal2TxContext->CellDescQId, &cellDescMsg); /* Increment the Timer_CU sequence number for this VcIndex */ (pAal2TxContext->Aal2TxDmemTable[VcIndex & DMEM_TABLE_INDEX_MASK].CuTimerSeqNum)++;}/****************************************************************************** * Function : aal2TxInit * * Description : This routine interprets the CP Init descriptor posted by * XP to this CP. Initializes DMEM table and CPS control * blocks, and sets the DMEM locations for RxByte processor to * write for both the scopes. * Parameters : Pointer to AAL2 CP Init Descriptor. * * Returns : TRUE/FALSE. * * Traceability : aal2_tx_design.doc. Section: 2.1. * ******************************************************************************/int8u aal2TxInit (Aal2CpInitDesc *cpInitDescriptor){ int32u TempCount = 0; PduHandle pduHandle; KsStatus status; /* Initialize the global memory pointer for Tx context variables */ pAal2TxContext = &(gAal2Context.Aal2TxContext); /* Get the CP Id for this CP */ gAal2TxCpId = ksCpGetId(); /* Get the base queue id of XP */ qsQueueGet(XPprocID, &gXpBaseQId, &TempCount); /* CU_Timer event queue is base queue + 1 */ pAal2TxContext->Aal2TxCuTimerEventQ = baseQueueId + 1; #ifdef TWO_AAL2_RX_CP_PER_PORT /* Get the queue id, where Tx module will en-queue the cell descriptor. * Check the architecture for AAL2 Tx CPs cluster, before assigning q ids. * For CP id 8 and 9, queue id should be 8, and, for 10, 11 it should be 12. * ****** This arrangement is for prototyping only ****** */ if ((gAal2TxCpId EQ 8) OR (gAal2TxCpId EQ 9)) { pAal2TxContext->CellDescQId = 8; } else { pAal2TxContext->CellDescQId = 12; }#else pAal2TxContext->CellDescQId = cpInitDescriptor->destId; Aal2TxDebugValPrint ("AAL2TxInit: Dest Q Id = ", pAal2TxContext->CellDescQId);#endif /* Initialize DMEM table */ for (TempCount = 0; TempCount < MAX_DMEM_TABLE_SIZE; TempCount++) { pAal2TxContext->Aal2TxDmemTable[TempCount].CuTimerSeqNum = 0; pAal2TxContext->Aal2TxDmemTable[TempCount].AtmSduBytesCount = 0; pAal2TxContext->Aal2TxDmemTable[TempCount].StfSequenceNumber = 0; pAal2TxContext->Aal2TxDmemTable[TempCount].CuTimerStarted = FALSE; pAal2TxContext->Aal2TxDmemTable[TempCount].CuTimerExpired = FALSE; pAal2TxContext->Aal2TxDmemTable[TempCount].AtmSduBufHandle = NOT_ALLOCATED; } /* Initialize CPS control blocks */ for (TempCount = 0; TempCount < MAX_CPS_CONTROL_BLOCKS; TempCount++) { pAal2TxContext->CpsControlBlocks[TempCount].VcIndex = INVALID_VC_ID; pAal2TxContext->CpsControlBlocks[TempCount].FwderProcDone = TRUE; pAal2TxContext->CpsControlBlocks[TempCount].CountAtmSdu = 0; } /* Set DMEM locations for the both the scopes for RxByte Processor */ for (TempCount = 0; TempCount < MAX_SCOPES; TempCount++) { pduHandle = pduHandleForScopeNumber (TempCount); pduRxBufHandleSet(pduHandle, 0); pduRxToDmem (pduHandle, (int32u*) rxTempPdu[TempCount]); pduRxFree(pduHandle); }#ifdef AAL2_STATISTICS /* ksPrintf ("AAL2 Tx - txAal2Pdus : %x, txCells : %x", &txCells, &txAal2Pdus); */#endif /* Register the IRQ handler for QMU errors */ ksEventRegisterInterrupt(ksEventIdQmuError, (KsFunc)&aal2CpQmuIrqHandler, (void*)0 ); /* Create AAL2 Tx Hdlr thread */ status = ksContextCreate (AAL2_TX_HDLR_STACK_SIZE, aal2TxHdlr, &aal2HdlrContext); if (status != ksStatusSuccess) { ksPanic (" Aal2 Tx Handler not Created "); } /* Create AAL2 Tx Fwdr thread */ status = ksContextCreate (AAL2_TX_FWDR_STACK_SIZE, aal2TxFwdr, &aal2FwdrContext); if (status != ksStatusSuccess) { ksPanic (" Aal2 Tx Forwarder not Created "); } /*Aal2TxDebugValPrint ("AAL2TxInit: aal2TxInit Completed for CpId = ", gAal2TxCpId);*/ return TRUE;}/****************************************************************************** * Function : aal2TxHdlr * * Description : Handler thread for the AAL2Tx Module. * * Parameters : void* arg: Not used. * * Returns : None. * * Traceability : aal2_tx_design.doc. Section: 2.3. * ******************************************************************************/int32u aal2TxHdlr (void* arg){ int16u Aal2TxDmemTableIndex = 0; int8u StfTableIndex = 0; int8u FirstStfByte = 0; int8u SecondStfByte = 0; int8u Stf1Position = 0; int8u CpsPaylodLength = 0; int8u StfSequenceNumber = 0; int8u PrevAtmSduLength = 0; int16u VcIndex = 0; int8u CountSduFrags = 0; static int8u NextCpcCtrlBlkId = 0; static int8u PrevCpcCtrlBlkId = 1; MergeSpc *mergeSpc = NULL; BsBufHandle AtmSduBufHandle = NOT_ALLOCATED; int8u CountNonAlignBytes = 0; PduHandle pduHandle = NULL; int8u *pFwdrProcDoneFlag = NULL; int32u *pDest = NULL; int32u *pSource = NULL;#ifdef AAL2_TX_DEBUG int32u *pInData=NULL; int16u TempCount = 0; #endif CpsDesc = qsMessageGetData (&(pAal2TxContext->CpsDescMsg)); memset(CpsDesc, 0, sizeof(Aal2CpsDesc)); while (TRUE) { /*Aal2TxDebugValPrint ("AAL2TxHdlr: Hdlr For CpId = ", gAal2TxCpId);*/ MSG_EVENT ("CPRC AAL2TX HDLR wait for message"); /* Till there is no message in the base queue, switch the context */ while (qsQueueGetLength (baseQueueId) EQ 0) { ksContextSwitch(aal2FwdrContext); } MSG_EVENT ("CPRC AAL2TX HDLR : PROCESSING START"); /* Start receiving the message */ qsMessageReceiveStart (baseQueueId, &(pAal2TxContext->CpsDescMsg)); /* Till message receive completes, switch the context */ while (qsMessageReceiveComplete (baseQueueId, &(pAal2TxContext->CpsDescMsg)) EQ FALSE) { ksContextSwitch(aal2FwdrContext); } bsBufferRead (CpsDesc->cpsPckPayload, 0, &txTempPdu[1], roundUp(CpsDesc->li+1,16)) ; /* Message has been successfully de-queued from this CP's base queue */ /* Get the VC Index from CPS Descriptor */ VcIndex = CpsDesc->egressVcIndex; /* Use lower 9 bits of VC Index to index in to the DMEM table. */ Aal2TxDmemTableIndex = VcIndex & DMEM_TABLE_INDEX_MASK; /* Check the following things: * If, previous CPS control block was filled for the same VC index, * as this CPS packet is meant for, then * while, previous CPS control block is being processed by Fwdr, * keep switching the context, because this CPS packet can * not be processed, until previous was done. */ /*Aal2TxDebugValPrint ("AAL2TxHdlr: VcIndex in Next CPS Block = ", pAal2TxContext->CpsControlBlocks[NextCpcCtrlBlkId].VcIndex); Aal2TxDebugValPrint ("AAL2TxHdlr: VcIndex in Prev CPS Block = ", pAal2TxContext->CpsControlBlocks[PrevCpcCtrlBlkId].VcIndex);*/ if (pAal2TxContext->CpsControlBlocks[PrevCpcCtrlBlkId].VcIndex EQ VcIndex) { /* Get the location of FwdrProcDone flag in control block */ pFwdrProcDoneFlag = &(pAal2TxContext->CpsControlBlocks[PrevCpcCtrlBlkId].FwderProcDone); while (*pFwdrProcDoneFlag EQ FALSE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -