📄 ixatmcodeletrxtx.c
字号:
/* For each Aal5 VC */ for (channelIdx=0; (sduCnt<numSdus) && (channelIdx < ixAtmRxTxNumChannelsConfigured); channelIdx++, sduCnt++) { if (ixAtmRxTxTxVcInfoTable[channelIdx].aalType == IX_ATMDACC_AAL5) { retval = ixAtmRxTxAal5CpcsTx (ixAtmRxTxTxVcInfoTable[channelIdx].connId, sduSize); if (retval != IX_SUCCESS) { IX_ATMCODELET_LOG ("Failed to send a pdu on channel...... %u\n", channelIdx); } } else { /* decrement the sduCnt a sdu was not sent on this vc */ sduCnt--; } } } return IX_SUCCESS; }/* -------------------------------------------------------------- Replenish buffers to the RxFree queue. Buffers are taken from the mbuf pool -------------------------------------------------------------- */voidixAtmRxTxRxFreeLowReplenish (IxAtmdAccUserId userId){ IX_OSAL_MBUF *mBuf; IX_STATUS retval; IxAtmConnId connId; UINT32 numFreeEntries; UINT32 cnt; connId = ixAtmRxTxRxVcInfoTable[userId].connId; /* Get the number of free entries in the RX Free queue */ retval = ixAtmdAccRxVcFreeEntriesQuery (connId, &numFreeEntries); if (retval != IX_SUCCESS) { IX_ATMCODELET_LOG("Failed to query depth of Rx Free Q for connection %u\n", connId); return; } /* Replenish Rx buffers */ for (cnt=0; cnt<numFreeEntries; cnt++) { /* Get an MBUF */ ixAtmUtilsMbufGet(IX_ATMCODELET_MBUF_SIZE, &mBuf); if (mBuf == NULL) { IX_ATMCODELET_LOG("Failed to get rx free mbuffers\n"); return; } if(IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBuf) != 0) { IX_ATMCODELET_LOG("Next Ptr != 0\n"); return; } IX_OSAL_ASSERT(IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBuf) == 0); /* * Set the number of bytes of data in this MBUF to the number of * payloads that will fit evenly into IX_ATMCODELET_MBUF_SIZE. */ IX_OSAL_MBUF_MLEN(mBuf) = (IX_ATMCODELET_MBUF_SIZE / ixAtmRxTxRxVcInfoTable[userId].bytesPerCell) * ixAtmRxTxRxVcInfoTable[userId].bytesPerCell; /* Send free buffers to NPE */ retval = ixAtmdAccRxVcFreeReplenish (connId, mBuf); if (retval != IX_SUCCESS) { /* Free the allocated buffer */ IX_ATMCODELET_LOG("Failed to pass Rx free buffers to Atmd \n"); ixAtmUtilsMbufFree(mBuf); return; } /* Update stats */ ixAtmRxTxStats->rxFreeBuffers++; }}/* -------------------------------------------------------------- Return an Aal0 packet. This assumes that the Packet will fit into a single mbuf. i.e. No chaining. -------------------------------------------------------------- */PRIVATE IX_STATUSixAtmRxTxAal0PacketBuild (int channelNum, UINT32 sizeInCells, IX_OSAL_MBUF **mBuf){ UINT8 *dataPtr; unsigned char headerChar1, headerChar2, headerChar3, headerChar4; UINT32 packetLen; UINT32 tmpLen; UINT32 cellDataSize = ixAtmRxTxTxVcInfoTable[channelNum].bytesPerCell; /* Initialise the returned pointer */ *mBuf = NULL; /* calculate the packet length */ packetLen = sizeInCells * cellDataSize; if (IX_ATMCODELET_MAX_PACKET_LEN < packetLen) { IX_ATMCODELET_LOG ("ixAtmRxTxAal0PacketBuild(): IX_ATMCODELET_MAX_PACKET_LEN < packetLen\n"); return IX_FAIL; } /* Get the first buffer */ ixAtmUtilsMbufGet (packetLen, mBuf); if (*mBuf == NULL) { IX_ATMCODELET_LOG ("ixAtmRxTxAal0PacketBuild() failed to get mBuf\n"); return IX_FAIL; } /* if the aaltype is aal0_52 then insert the header into the buffer */ if (ixAtmRxTxTxVcInfoTable[channelNum].aalType == IX_ATMDACC_AAL0_52) { dataPtr = (UINT8 *) IX_OSAL_MBUF_MDATA(*mBuf); tmpLen = packetLen; headerChar1 = (char)(ixAtmRxTxTxVcInfoTable[channelNum].atmHeader >> 24); headerChar2 = (char)((ixAtmRxTxTxVcInfoTable[channelNum].atmHeader >> 16) & 0xFF); headerChar3 = (char)((ixAtmRxTxTxVcInfoTable[channelNum].atmHeader >> 8) & 0xFF); headerChar4 = (char)(ixAtmRxTxTxVcInfoTable[channelNum].atmHeader & 0xFF); while(tmpLen > 0) { /* get the dataPtr and insert the header */ *dataPtr++ = headerChar1; *dataPtr++ = headerChar2; *dataPtr++ = headerChar3; *dataPtr++ = headerChar4; /* increment to the next header position */ dataPtr = dataPtr + 48; /* decrement the packetlen */ tmpLen = tmpLen - ixAtmRxTxTxVcInfoTable[channelNum].bytesPerCell; } } IX_OSAL_ASSERT(IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(*mBuf) == 0); /* Setup the MBUF, * N.B. for simplicity not filling in payload */ IX_OSAL_MBUF_PKT_LEN(*mBuf) = packetLen; return IX_SUCCESS;}/* -------------------------------------------------------------- Return an Aal5 PDU. This assumes that the PDU will fit into a single mbuf. i.e. No chaining. -------------------------------------------------------------- */PRIVATE IX_STATUSixAtmRxTxAal5CpcsPduBuild (UINT32 sduLen, IX_OSAL_MBUF **mBuf){ int pduLen; unsigned char* trailer = NULL; if (IX_ATMCODELET_MAX_SDU_LEN < sduLen) { IX_ATMCODELET_LOG ("ixAtmRxTxAal5CpcsPduBuild(): IX_ATMCODELET_MAX_SDU_LEN < sduLen\n"); return IX_FAIL; } /* CASE 1: Enough bytes left in CELL to store trailer */ if ((sduLen % IX_ATM_CELL_PAYLOAD_SIZE) == IX_ATMCODELET_SAME_CELL_MAX_OFFSET) { pduLen = sduLen + IX_ATMCODELET_TRAILER_SIZE; } /* CASE 2: More than enough bytes in CELL to store trailer */ else if ((sduLen % IX_ATM_CELL_PAYLOAD_SIZE) < IX_ATMCODELET_SAME_CELL_MAX_OFFSET) { pduLen = (sduLen - (sduLen % IX_ATM_CELL_PAYLOAD_SIZE)) + IX_ATM_CELL_PAYLOAD_SIZE; } /* CASE 3: Not enough bytes in CELL to store trailer. Need another CELL */ else { pduLen = (sduLen - (sduLen % IX_ATM_CELL_PAYLOAD_SIZE)) + (IX_ATM_CELL_PAYLOAD_SIZE * 2/* Need another CELL*/); } /* Initialise the returned pointer */ *mBuf = NULL; /* Get the first buffer */ ixAtmUtilsMbufGet (pduLen, mBuf); if (*mBuf == NULL) { IX_ATMCODELET_LOG ("ixAtmRxTxAal5CpcsPduBuild() failed to get mBuf\n"); return IX_FAIL; } IX_OSAL_ASSERT(IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(*mBuf) == 0); trailer = (unsigned char*)IX_OSAL_MBUF_MDATA(*mBuf) + pduLen - 8; /*Fill out the relevant inf/trailero in the trailer*/ trailer[IX_ATMCODELET_UUI_OFFSET] = IX_ATMCODELET_DEFAULT_UUI; trailer[IX_ATMCODELET_CPI_OFFSET] = IX_ATMCODELET_DEFAULT_CPI; trailer[IX_ATMCODELET_SDU_LEN_LO_BYTE] = sduLen & IX_ATMCODELET_FIRST_BYTE_MASK; trailer[IX_ATMCODELET_SDU_LEN_HI_BYTE] = (sduLen & IX_ATMCODELET_SECOND_BYTE_MASK) >> IX_ATMCODELET_SHIFT_EIGHT_BITS; IX_OSAL_MBUF_PKT_LEN(*mBuf) = pduLen; IX_OSAL_MBUF_MLEN(*mBuf) = pduLen; return IX_SUCCESS;}/* -------------------------------------------------------------- Reset the counters. -------------------------------------------------------------- */PRIVATE voidixAtmRxTxStatsReset (void){ if (NULL != ixAtmRxTxStats) { ixAtmRxTxStats->txPdus = 0; ixAtmRxTxStats->txBytes = 0; ixAtmRxTxStats->rxPdus = 0; ixAtmRxTxStats->rxBytes = 0; ixAtmRxTxStats->txDonePdus = 0; ixAtmRxTxStats->rxFreeBuffers = 0; ixAtmRxTxStats->txPdusSubmitFail = 0; ixAtmRxTxStats->txPdusSubmitBusy = 0; ixAtmRxTxStats->rxPdusInvalid = 0; }}/* -------------------------------------------------------------- The callback is called whenever the TxDone queue reaches a certain level. Mbufs are simply returned to the vxWorks pool. -------------------------------------------------------------- */PRIVATE voidixAtmRxTxTxDoneCallback (IxAtmdAccUserId userId, IX_OSAL_MBUF *mbufPtr){ ixAtmRxTxStats->txDonePdus++; /* Return the buffer to the vxWorks pool */ ixAtmUtilsMbufFree(mbufPtr);}/* -------------------------------------------------------------- This callback is called when a PDU is recieved. The Mbuf is freed to the vxWorks pool. -------------------------------------------------------------- */PRIVATE voidixAtmRxTxRxCallback (IxAtmLogicalPort port, IxAtmdAccUserId userId, IxAtmdAccPduStatus pduStatus, IxAtmdAccClpStatus clp, IX_OSAL_MBUF *mbufPtr){ UINT32 sizeInCells; IxAtmdAccAalType aalType; if (mbufPtr == NULL) { IX_ATMCODELET_LOG("rxCallback called with NULL mbufPtr\n"); return; } /* invalidate cache */ ixAtmRxTxRxInvalidate( mbufPtr ); /* Size of the data transmitted in CELLS */ sizeInCells = IX_OSAL_MBUF_PKT_LEN(mbufPtr) / ixAtmRxTxRxVcInfoTable[userId].bytesPerCell; if (pduStatus == IX_ATMDACC_MBUF_RETURN) { /* Return this buffer to the pool */ ixAtmUtilsMbufFree (mbufPtr); return; } aalType = ixAtmRxTxRxVcInfoTable[userId].aalType; if ((aalType == IX_ATMDACC_AAL0_48) || (aalType == IX_ATMDACC_AAL0_52)) { if (pduStatus != IX_ATMDACC_AAL0_VALID) { ixAtmRxTxStats->rxPdusInvalid++; } /* Aal0 should always be valid */ IX_OSAL_ASSERT(pduStatus == IX_ATMDACC_AAL0_VALID); } else { /* Must be Aal5 */ IX_OSAL_ASSERT(aalType == IX_ATMDACC_AAL5); /* Check PDU status, could be valid, partial or crc error */ if (pduStatus != IX_ATMDACC_AAL5_VALID) { ixAtmRxTxStats->rxPdusInvalid++; IX_ATMCODELET_LOG("rxCallback called with CRC error\n"); } } /* Update stats */ ixAtmRxTxStats->rxPdus++; ixAtmRxTxStats->rxBytes += IX_OSAL_MBUF_PKT_LEN(mbufPtr); /* Return this buffer to the pool */ ixAtmUtilsMbufFree (mbufPtr); return;}/* -------------------------------------------------------------- Transmit an Atm PDU of the specified length on the channel associated with connId. -------------------------------------------------------------- */PRIVATE IX_STATUSixAtmRxTxAal5CpcsTx (IxAtmConnId connId, UINT32 sduLen){ int sizeInCells = 0; IX_OSAL_MBUF *mBuf; /* Build an Aal5 PDU for this SDU */ if (ixAtmRxTxAal5CpcsPduBuild (sduLen, &mBuf) != IX_SUCCESS) { return IX_FAIL; } /* Size of the data transmitted in CELLS */ sizeInCells = IX_OSAL_MBUF_PKT_LEN(mBuf) / IX_ATM_CELL_PAYLOAD_SIZE; return ixAtmRxTxWithRetiesSend (connId, mBuf, sizeInCells);}/* -------------------------------------------------------------- Transmit an Aal0 Packet of the specified length on the channel associated with connId. -------------------------------------------------------------- */PRIVATE IX_STATUSixAtmRxTxAal0Tx (int channelNum, UINT32 sizeInCells){ IX_OSAL_MBUF *mBuf; /* Build an Aal0 Packet */ if (ixAtmRxTxAal0PacketBuild (channelNum, sizeInCells, &mBuf) != IX_SUCCESS) { return IX_FAIL; } return ixAtmRxTxWithRetiesSend (ixAtmRxTxTxVcInfoTable[channelNum].connId, mBuf, sizeInCells);}PRIVATE IX_STATUSixAtmRxTxWithRetiesSend (IxAtmConnId connId, IX_OSAL_MBUF* mBuf, UINT32 sizeInCells){ IX_STATUS status; UINT32 retryCount; /* flush cache */ ixAtmRxTxTxFlush( mBuf ); /* Transmit with retries */ for (status=IX_FAIL, retryCount=0; ((retryCount<IX_ATMCODELET_TX_RETRY_CNT) && (status!=IX_SUCCESS)); retryCount++) { status = ixAtmdAccTxVcPduSubmit(connId, mBuf, IX_ATMCODELET_DEFAULT_CLP, sizeInCells); if (status != IX_SUCCESS) { if (status != IX_ATMDACC_BUSY) { ixAtmRxTxStats->txPdusSubmitFail++; /* stats for fail */ IX_ATMCODELET_LOG("txAndRetry() failed when sending pkt\n"); break; } ixAtmRxTxStats->txPdusSubmitBusy++; /* stats for busy */ ixOsalSleep(IX_ATMCODELET_TX_RETRY_DELAY); } } if (status == IX_SUCCESS) { /* Update stats */ ixAtmRxTxStats->txPdus++; ixAtmRxTxStats->txBytes += IX_OSAL_MBUF_PKT_LEN(mBuf); } else { /* release the mbuf */ ixAtmUtilsMbufFree (mBuf); status = IX_FAIL; } return status;}/* ---------------------------------------------------*/PRIVATE voidixAtmRxTxTxFlush(IX_OSAL_MBUF * mbufPtr){ while (mbufPtr != NULL) { IX_OSAL_CACHE_FLUSH(IX_OSAL_MBUF_MDATA(mbufPtr), IX_OSAL_MBUF_MLEN(mbufPtr)); mbufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr); } return;}/* ---------------------------------------------------*/PRIVATE voidixAtmRxTxRxInvalidate(IX_OSAL_MBUF * mbufPtr){ while (mbufPtr != NULL) { IX_OSAL_CACHE_INVALIDATE(IX_OSAL_MBUF_MDATA(mbufPtr), IX_OSAL_MBUF_MLEN(mbufPtr)); mbufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr); } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -