📄 aal2rxcp.c
字号:
/* * aal2Rx.c * * DESCRIPTION: * This file contain the code for AAL2 Rx CPRC. Functions * related to aal2Rx initialization, thread creation, Handler * and Forwarder are given here. * * aal2RxInit() initializes the global data structures, payload for * SDP to DMEM data transfer required for the operation of handler * and forwarder threads. It also brings up the two threads * aal2RxHdlr and aal2RxFwdr. * * aal2RxHdlr() dequeues ATM cells from the base queue, performs checks * such as parity, SN. Then forwards the payload to the SDP for further * processing. It also takes care of forwarding any partial payload or * header which needs processing to the SDP. * * aal2RxFwdr() retrieves CPS packets from the SDP, initiates lookups, * builds CPS packet descriptor and finally enqueues to the destination * obtained from the lookup. Incase of partial header and partial payload * the header bytes or unaligned data are stored for further processing * by the handler. * *//* * Copyright (c) 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. */#include <dcpKernelSvcs.h>#include <dcpQueueSvcs.h>#include <dcpTableSvcs.h>#include <dcpBufferSvcs.h>#include <dcpPduSvcs.h>#include <dcpTypes.h>#include <bsBuffer.h>/* Header files with definitions for ATM */#include <atm.h>#include <atmCellDesc.h>#include <aal2TableDefs.h>/* Header files with definitions for AAL2 */#include <aal2.h>#include <aal2Desc.h>/* Header files with definitions for AAL2 Rx */#include <rcSdpAal2RxApiIf.h>#include <aal2Rx.h>#include <aal2RxIf.h>#include <aal2Tx.h>#include <aal2TxIf.h>#include <aal2Init.h>#include <systemServicesLocal.h>#include <errorHandling.h>#ifdef DEBUG_64int8u ALIGNED64 aal2Payload[64];#endif/******************************************************* * Global variable declaration *******************************************************/AAL2_RX_CONTEXT *gpAal2RxContext; /* AAL2 Rx context pointer */extern PDU ALIGNED64 rxTempPdu[MAX_SCOPES]; /* DMEM for payload transfer from SDP to DMEM */extern PDU ALIGNED64 txTempPdu[MAX_SCOPES]; /* DMEM for payload transfer from DMEM to SDP */extern QsMessage ALIGNED64 cellDescMsg; /* Queue descriptor for ATM cells */extern CellDescriptor *cellDescPtr; /* Pointer to ATM cell descriptor */extern BsPoolId poolId; /* AAL2 CP pool Id */extern QsQueueId baseQueueId; /* Input queue Id of the AAL2 CP */extern KsContext aal2HdlrContext; /* KsContext of the AAL2 Hdlr thread */extern KsContext aal2FwdrContext; /* KsContext of the AAL2 Fwdr thread */#ifndef SIM#define AAL2_STATISTICS#endif#ifdef AAL2_STATISTICS/* Variable declared for storing the statistics regarding AAL2 Rx. */extern int32u rxAal2LengthErr;extern int32u rxAal2Pdus;extern int32u Aal2ParityErr;extern int32u Aal2SNErr;extern int32u rxInvalidCid;extern int32u Aal2Crc5Err;extern int32u rxSent;extern int32u aal2EnqueueFail;#endifextern Boolean payloadEnqueue;extern BsBufHandle lastBufferEnqueued;int32u bufferAllocFail;/******************************************************* * Function declarations *******************************************************/int32u aal2RxFwdr(void *arg);int32u aal2RxHdlr(void *arg);void aal2RxCancelReasm(AAL2RxVcTable *aal2RxVcTable);int32u aal2CpQmuIrqHandler(void *);/***************************************************************** * Function : aal2RxInit * * Description : This function initializes the global variables * of the AAL2_RX_CONTEXT and also does * initialization of a few variable which need * not be repeated again and will save CPU * cycles. Finally it starts the two threads * aal2RxHdlr() and aal2RxFwdr(). * * Parameters : AAL2 CP init descriptor. * * Returns : void. * * Traceability : AAL2_Rx_HLD.doc section: 3.9. * *****************************************************************/void aal2RxInit(Aal2CpInitDesc *aal2RxCpInitDesc){ PduHandle pduHandle; int16u i; int8u scope; /* Initialize the AAL2 Rx context pointer */ gpAal2RxContext = &gAal2Context.Aal2RxContext; /* Store the table Id in the AAL2 Rx context */ gpAal2RxContext->tableId = (TsTableId) aal2RxCpInitDesc->tableId; /* Allocating and initializing CPS descriptor array */ for (i = 0; i < NUM_CPS_DESCRIPTORS; i++) { gpAal2RxContext->cpsDescArray[i] = (Aal2CpsDesc *) qsMessageGetData (&gpAal2RxContext->cpsDescriptor[i]); /* To avoid the DMEM read before write warnings */ memset(gpAal2RxContext->cpsDescArray[i], 0, sizeof(Aal2CpsDesc)); } /* Initialization for table lookups which need not be repeated */ gpAal2RxContext->key.keyData = (int32u *)&gpAal2RxContext->aal2ConnectionId; gpAal2RxContext->key.maskLenBits = 0; /* Set all the buffer handles in VC Table to NOT_ALLOCATED */ for (i = 0; i < AAL2_RX_VC_TABLE_SIZE; i++) { gpAal2RxContext->aal2RxVcTable[i].bufHandlePtr = NOT_ALLOCATED; } /* Preset TsEntry array for table lookups */ for (i = 0; i < NUM_TLU_REQ_SLOTS; i++) { gpAal2RxContext->entry[i].length = 16; gpAal2RxContext->entry[i].offset = 0; gpAal2RxContext->entry[i].reqTag = tsRequestTag(i); gpAal2RxContext->entry[i].respTag = i * 2; } /* Initialize the Cell and partial payload buffer pointers in the VCCBs */ gpAal2RxContext->vccb[0].partialPayload = txTempPdu[0]; gpAal2RxContext->vccb[0].cellPayload = txTempPdu[1]; gpAal2RxContext->vccb[1].partialPayload = txTempPdu[0]; gpAal2RxContext->vccb[1].cellPayload = txTempPdu[1]; /* Set the DMEM addresses for both the scopes of Forwarder and Handler, * so that this need not be set again and again. */ for (scope = 0; scope < MAX_SCOPES; scope++) { pduHandle = pduHandleForScopeNumber(scope); /* Set the bufHandle to 0, DMA address for the forwarder */ pduRxBufHandleSet(pduHandle, 0); pduRxToDmem(pduHandle, (int32u*) rxTempPdu[scope]); pduRxFree(pduHandle); /* Set the bufHandle to 0, DMA address for the forwarder */ pduTxBufHandleSet(pduHandle, 0); } bufferAllocFail = 0;#ifdef AAL2_STATISTICS ksPrintf ("AAL2 Rx - rxAal2LengthErr: 0x%x", &rxAal2LengthErr); ksPrintf ("AAL2 Rx - Aal2ParityErr : 0x%x, Aal2SNErr : 0x%x", &Aal2ParityErr, &Aal2SNErr); ksPrintf ("AAL2 Rx - rxInvalidCid : 0x%x, Aal2Crc5Err : 0x%x", &rxInvalidCid, &Aal2Crc5Err); ksPrintf ("AAL2 Rx - aal2EnqueueFail: 0x%x", &aal2EnqueueFail); ksPrintf("AAL2 Rx - Buffer Alloc Fail: 0x%x", &bufferAllocFail);#endif /* Register the IRQ handler for QMU errors */ ksEventRegisterInterrupt(ksEventIdQmuError, (KsFunc)&aal2CpQmuIrqHandler, (void*)0 ); /* Create the AAL2 Rx Forwarder context */ ksContextCreate(AAL2_RX_FWDR_THREAD_STACK_SIZE, aal2RxFwdr, &aal2FwdrContext); /* Create the AAL2 Rx Handler context */ ksContextCreate(AAL2_RX_HDLR_THREAD_STACK_SIZE, aal2RxHdlr, &aal2HdlrContext);}/***************************************************************** * Function : aal2RxFwdr * * Description : This function is a thread invoked by aal2Rx(). * This function get the CPS headers and payloads * from the RxSDP. It does a lookup for the CID * and VC index, stores the CPS header, payload, * lookup results in a CPS descriptor and queues * to the adjacent AAL2. * * Parameters : Void pointer. * * Returns : Int32u * * Traceability : AAL2_Rx_HLD.doc section: 3.11. * *****************************************************************/int32u aal2RxFwdr(void *arg){ CidTabEntryData *cidTableData; VCCB *cur_vccb; AAL2_RX_EXTRACT *extractSpace; AAL2RxVcTable *aal2RxVcTable; Aal2CpsDesc *pCpsDesc; BsBufHandle bufHandle; PduHandle pduHandle; int32u inVcIndex; int8u cpsHdrLen, cpsPayloadLen, endOfCell; int8u NumCpsPckGot = 0, cpsPckCount; int8u offset = 0, fwdrVccb = 0, fwdrScopeNum = 0;#ifdef DEBUG_64 int8u i;#endif while(1) { /* Get the current VCCB for the forwarder, check if the current * VCCB is locked by the handler, if so then return context to * the handler. */ MSG_EVENT("CPRC AAL2 RX FORWARDER CONTEXT: PROCESSING START"); cur_vccb = &gpAal2RxContext->vccb[fwdrVccb]; while (!cur_vccb->lockFlag) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxFwdr: Waiting for current VCCB flag");#endif ksContextSwitch (aal2HdlrContext); } /* Get the current VC Index from the VCCB */ inVcIndex = cur_vccb->ingressVcIndex; aal2RxVcTable = &gpAal2RxContext->aal2RxVcTable[inVcIndex & 0x01FF]; /* Start receiving CPS packets from Extract space */ do { do { /* Get the current scope */ pduHandle = pduHandleForScopeNumber(fwdrScopeNum); MSG_EVENT("CPRC: AAL2 RX FORWARDER wait for scope"); /* Check if extract space is available for the current * scope, if not then switch to the other thread. */ while (IS_EXTRACT_SPACE_BUSY()) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxFwdr: Waiting for Extract Space");#endif ksContextSwitch (aal2HdlrContext); } MSG_EVENT("CPRC: AAL2 RX FORWARDER got scope"); /* Else read the first two bytes of the extract space. This * will give the length of the header in the extract space * and length of payload to be transferred to DMEM. * extractSpace = (AAL2_RX_EXTRACT *) pduHandle->extract; */ extractSpace = (AAL2_RX_EXTRACT *) pduRxHeaderGet(pduHandle); /* This for loop has been added to introduce delay, because * the extract space takes a delay of few cycles to actually * get the value. */ while (!extractSpace->extractAvailFlag) { ; /* Don't do anything here */ } if (extractSpace->goodCpsPacket) {#ifdef DCP_DEBUG_1 ksPrintf ("extractSpace->goodCpsPacket");#endif /* No errors found in CPS packet */ cpsHdrLen = extractSpace->cpsHdrLen; cpsPayloadLen = extractSpace->cpsPayloadLen; if (extractSpace->cpsPckComplete) { while (bsError(bufHandle = bsBufferAllocate(poolId))) { bufferAllocFail++; } aal2RxVcTable->offset = 0; /* Write payload to SDRAM */ bsBufferWrite(rxTempPdu[fwdrScopeNum], 64, bufHandle, 0);#ifdef DEBUG_64 while (!bsBufferWriteComplete ()) ; ksPrintf ("cid : %d VcIndex : %d",extractSpace->cid,inVcIndex);#endif pCpsDesc = gpAal2RxContext->cpsDescArray[NumCpsPckGot]; pCpsDesc->cpsPckPayload = bufHandle; pCpsDesc->li = extractSpace->li; pCpsDesc->uui = extractSpace->uui; gpAal2RxContext->aal2ConnectionId = composeCidIndex(inVcIndex, extractSpace->cid); tsEntryLookup(gpAal2RxContext->tableId, &gpAal2RxContext->key, &gpAal2RxContext->entry[NumCpsPckGot]); NumCpsPckGot++; } else if (cpsHdrLen) /* CPS HEADER FOUND IN EXTRACT SPACE */ { #ifdef DCP_DEBUG_1 ksPrintf ("cpsHdrLen : %d",cpsHdrLen);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -