📄 aal2rxcp.c
字号:
* In case, they are equal, the parity is correct. */ receivedSTF = vccb->cellPayload[0]; /* ksPrintf("Aal2RxHdlr: STF %x", receivedSTF); */ if (gAal2ParityTable[(receivedSTF >> 1)] != receivedSTF ) {#ifdef AAL2_STATISTICS Aal2ParityErr++ ;#endif /* Check whether the forwarder is working on a cell * which has the same VC index. * If yes then the handler has to return the control to forwarder. * This is because the forwarder may find a partial CPS packet or * header at the end of the previous cell which may be require * recirculation. */ if (prevVccb->ingressVcIndex == ingressVcIndex) { while (prevVccb->lockFlag) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxHdlr: Waiting for a back to back packet");#endif ksContextSwitch(aal2FwdrContext); } } /* * If parity is incorrect, call the function aal2RxCancelReasm(). * Go to START. */ aal2RxCancelReasm(aal2RxVcTable); bsBufferFree (cellDescPtr->Bh) ; continue; } else { /* In case, parity from the parityTable and copyOfReceivedSTF * are equal, the parity is correct. Store the SN and offset * information */ receivedSN = (receivedSTF & 0x02) >> 1; receivedOffset = receivedSTF >> 2 ; /* Compare the sequence number in the received CPS PDU * with the expected SN present in the DMEM table. */ if (receivedSN != expectedSN) { /* If the sequence number check failed, * The sequence number of the current CPS PDU is XORed with 1. * The DMEM table is updated with this info. * Then Call the function or macro aal2RxCancelReasm(). */ AAL2_RX_setSeqNo(aal2RxVcTable, receivedSN); /* Check whether the forwarder is working on a cell * which has the same VC index. * If yes then the handler has to return the control to forwarder. * This is because the forwarder may find a partial CPS packet or * header at the end of the previous cell which may be require * recirculation. */ if (prevVccb->ingressVcIndex == ingressVcIndex) { while (prevVccb->lockFlag) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxHdlr: Waiting for a back to back packet");#endif ksContextSwitch(aal2FwdrContext); } } aal2RxCancelReasm(aal2RxVcTable);#ifdef AAL2_STATISTICS Aal2SNErr ++ ;#endif /* If the offset has a value greater than or equal to 47, * The re-circulation to TxSDP need not be done in this case also. */ if (receivedOffset >= CPS_PDU_PAYLOAD_SIZE) { bsBufferFree (cellDescPtr->Bh) ; continue; } } else { /* The sequence number information is updated in the DMEM table */ AAL2_RX_setSeqNo(aal2RxVcTable, receivedSN); /* If the offset has a value greater than or equal to 48, * The re-circulation to TxSDP need not be done in this case * also. Call the function aal2RxCancelReasm(). */ if (receivedOffset >= CPS_PDU_SIZE) { /* Check whether the forwarder is working on a cell * which has the same VC index. * If yes then the handler has to return the control to forwarder. * This is because the forwarder may find a partial CPS packet or * header at the end of the previous cell which may be require * recirculation. */ if (prevVccb->ingressVcIndex == ingressVcIndex) { while (prevVccb->lockFlag) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxHdlr: Waiting for a back to back packet");#endif ksContextSwitch(aal2FwdrContext); } } aal2RxCancelReasm(aal2RxVcTable); bsBufferFree (cellDescPtr->Bh) ; continue; } } /* Check for the availability of the merge space */ while (IS_MERGE_SPACE_BUSY()) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxHdlr: Waiting for Merge space");#endif ksContextSwitch(aal2FwdrContext); } /* Put the cell header fields into merge register space */ aal2_Rx_Merge = (AAL2_RX_MERGE *)pduTxHeaderGet(pduHandle); /* Set the merge space flag to 0 */ aal2_Rx_Merge->first_byte.ibyte = 0; /* DMA the cell payload to TxSDP using TxCB */ pduTxFromDmem(pduHandle,(int32u*) vccb->cellPayload,48); /* Save the STF's OSF information in the * MERGE space for processing by txSDP */ aal2_Rx_Merge->stfOffset = receivedOffset ; aal2_Rx_Merge->first_byte.bits.offsetInfo = receivedOffset ; /* Check whether the forwarder is working on a cell * which has the same VC index. * If yes then the handler has to return the control to forwarder. * This is because the forwarder may find a partial CPS packet or * header at the end of the previous cell which may be require * recirculation. */ if (prevVccb->ingressVcIndex == ingressVcIndex) { while (prevVccb->lockFlag) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxHdlr: Waiting for a back to back packet");#endif ksContextSwitch(aal2FwdrContext); } } iflag = aal2RxVcTable->hdrLen; /* * If Flag value is zero, and the buffer handle corres * ponding to DMEM is not NULL, jump to Partial Payload * processing. */ if (iflag) { if (receivedOffset) { /* * Update the header count information in * the merge space register definition. */ aal2_Rx_Merge->first_byte.bits.headerFlag = iflag; /* Extract CID, LI (assumed to be 0 if iflag == 2) info from * the DMEM table and update this in TXSDP_Merge0(bits 15:8) * and TXSDP_Merge0(bits 23:16). * Also, increment TxSDP_Merge1(bits 31:24) by value iflag. */ aal2_Rx_Merge->cidPart = aal2RxVcTable->cid; aal2_Rx_Merge->liUuiPart = (aal2RxVcTable->li << 2) | (aal2RxVcTable->uui >> 3); aal2_Rx_Merge->first_byte.bits.offsetInfo += iflag; /* Reset the header len in the DMEM table */ aal2RxVcTable->hdrLen = 0 ; } else { /* This is an error. We have a few header bytes in the table, * and the very first byte in the new cell is a CPS header. * The DMEM table corresponding to this VC index needs to be * cleared. Then proceed with normal transaction. */ aal2RxCancelReasm(aal2RxVcTable); } } else { if ((aal2RxVcTable->offset) && (aal2RxVcTable->bufHandlePtr != NOT_ALLOCATED)) { /* Partial Payload Processing: * Go to DMEM column corresponding to ingress VC index. * Extract offset information from the DMEM table. * PAY_BYTES := offset mod 16. */ PAY_BYTES = (AAL2_RX_GetBufOffset(aal2RxVcTable)) % 16; if (PAY_BYTES) { aal2RxVcTable->offset -= PAY_BYTES ; /* * Read the unaligned bytes of partial payload from SDRAM to DMEM. * HERE THERE IS NO NEED TO READ ALL THE PAYLOAD BYTES ONTO * THE DMEM. THE PARTIAL PAYLOAD CAN BE READ FROM offset - * (offset % 16) AND (offset % 16) BYTES COULD BE READ. THIS * WILL FINALLY SAVE CYCLES IN BUFFER READ AND WHILE SETTING * THE puPartial POINTER. */ bsBufferRead(aal2RxVcTable->bufHandlePtr, aal2RxVcTable->offset, (int8u *)vccb->partialPayload, 16); /* * As the payload bytes, which are unaligned are only * re-circulated the offset information in the DMEM * table has to be updated after the transmission of * the unaligned payload bytes to TxSDP. This has to * be done, because after re-circulation via RxSDP, * the remaining payload shall be written in a 16 byte * aligned boundary. */ puPartial = (int32u *) &vccb->partialPayload[0]; /* * Update TxSDPn_Merge1 with value * equal to OSF(STF) + PAY_BYTES information. */ aal2_Rx_Merge->first_byte.bits.offsetInfo += PAY_BYTES ; /* Keep checking whether the Buffer Read had been * completed or not. During this wait, the Handler * module may surrender the control to the Aal2Rx, * so that forwarder can do useful processing. */ while (!bsBufferReadComplete()) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxHdlr: Waiting for buffer read to complete");#endif ksContextSwitch(aal2FwdrContext); } /* Extract Partial Payload information and * update this in the merge space registers */ aal2_Rx_Merge->payLoadWord4 = *(puPartial + 3); aal2_Rx_Merge->payLoadWord3 = *(puPartial + 2); aal2_Rx_Merge->payLoadWord2 = *(puPartial + 1); aal2_Rx_Merge->payLoadWord1 = *puPartial; } } } } /* Release the merge space to the TxSDP to process * the cell header and cell payload information. */ pduTxFree(pduHandle); /* * If VCCB locked has not been released by the * forwarder, then return execution to the aal2RxFwdr. */ while (vccb->lockFlag) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxHdlr: Waiting for lock to be released by fwdr");#endif ksContextSwitch(aal2FwdrContext); } /* Store the VC index into VCCB. */ vccb->ingressVcIndex = ingressVcIndex; /* Lock the VCCB when data transfer to SDP starts so * that Forwarder can work on this VCCB.*/ vccb->lockFlag = LOCKED; /* Store the next VCCB number in the AAL2_RX_CONTEXT. */ hdlrVccb ^= 1; bsBufferFree (cellDescPtr->Bh) ; MSG_EVENT("CPRC AAL2 RX HANDLER CONTEXT: PROCESSING END"); } /* End of while (1) */ return TRUE;}/******************************************************************** * Function : aal2RxCancelReasm * * Description : This function erases the information of * the previous partial buffers * * Parameters : None * * Returns : Void * * Traceability : AAL2_Rx_HLD.doc section: 3.10. * ********************************************************************/void aal2RxCancelReasm(AAL2RxVcTable *aal2RxVcTable){ /* * Go to the DMEM table and find whether * there was any partial CPS Packet in the last cell. */ /* * In case, there was a partial CPS Packet in the last cell * corresponding to the same VCC, * free the buffer handle and set it to NULL and * initialize other fields in the DMEM table to zeros. * This shall help the Forwarder to discard the partial * CPS Packet information supplied by the RxSDP on the other side. * All these processing is to ensure that the partial portion of * CPS Packet payload , which was present in the earlier cell, * should have to be discarded. */ if (aal2RxVcTable->bufHandlePtr != NOT_ALLOCATED) { /* Deallocate the buffer handle corresponding to * the entry in the DMEM table. */ bsBufferFree (aal2RxVcTable->bufHandlePtr) ; aal2RxVcTable->bufHandlePtr = NOT_ALLOCATED ; } AAL2_RX_setBufOffset(aal2RxVcTable,0) ; /* No. of bytes in buffer */ /* * Initialise the other fields of the entries to NULL aal2RxVcTable->cid = 0 ; */ aal2RxVcTable->hdrLen = 0 ; return ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -