📄 ixatmcodeletrxtx.c
字号:
/** * @file IxAtmCodeletRxTx.c * * @date 20-May-2002 * * @brief Rx and Tx Transport for IXP400 Atm Codelet (IxAtmCodelet) * * Functions implemented in this file: * ixAtmRxTxInit * ixAtmRxTxStatsGet * ixAtmRxTxChannelsProvision * ixAtmRxTxSdusSend * * @par * IXP400 SW Release version 2.1 * * -- Copyright Notice -- * * @par * Copyright (c) 2001-2005, Intel Corporation. * All rights reserved. * * @par * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Intel Corporation nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * @par * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * * @par * -- End of Copyright Notice -- *//* * User defined include files. */#if defined(__wince) && defined(IX_USE_SERCONSOLE) #include "IxSerConsole.h" #define printf ixSerPrintf #define gets ixSerGets#endif#include "IxOsal.h"#include "IxAtmdAcc.h"#include "IxAtmCodelet_p.h"#include "IxAtmCodelet.h"/* * #defines and macros */#define IX_ATMCODELET_TX_RETRY_CNT (50) /* Number of retries before failing to transmit a PDU */#define IX_ATMCODELET_TX_RETRY_DELAY (100) /* Number of Ms to delay on retry *//* Aal5 PDU <------- trailer --------> +------------------------------------------------------+ | Payload | PAD | UU | CPI | Length | CRC| +------------------------------------------------------+ | 1 - 65,535 | 0-47 | 1 | 1 | 2 | 4 | */#define IX_ATMCODELET_TRAILER_SIZE (8) /* Atm trailer size in bytes. UU+CPI+Length+CRC */#define IX_ATMCODELET_SDU_LEN_LO_BYTE (3) /* Offset in trailer to the low byte of SDU length */#define IX_ATMCODELET_SDU_LEN_HI_BYTE (2) /* Offset in trailer to the high bye of SDU length field */#define IX_ATMCODELET_CPI_OFFSET (1) /* Offset to Common Part Indicator field */#define IX_ATMCODELET_UUI_OFFSET (0) /* Offset to User-User field */#define IX_ATMCODELET_DEFAULT_CPI (0) /* Default Common Part Indicator field value */#define IX_ATMCODELET_DEFAULT_UUI (9) /* Default User-User field value */#define IX_ATMCODELET_SHIFT_EIGHT_BITS (8) /* Operand to << and >> operators */#define IX_ATMCODELET_MAX_SDU_LEN (65535) /* Max length of Aal5 SDU */#define IX_ATMCODELET_MAX_PACKET_LEN (65535) /* Max length of Aal0 Packet *//* Max offset in an ATM cell */#define IX_ATMCODELET_FIRST_BYTE_MASK (0x00ff)#define IX_ATMCODELET_SECOND_BYTE_MASK (0xff00)#define IX_ATMCODELET_SAME_CELL_MAX_OFFSET (IX_ATM_CELL_PAYLOAD_SIZE-IX_ATMCODELET_TRAILER_SIZE)#define IX_ATMCODELET_NEW_CELL_THRESHOLD (IX_ATMCODELET_SAME_CELL_MAX_OFFSET+1)#define IX_ATMCODELET_NEW_CELL_MAX_OFFSET (IX_ATMCODELET_SAME_CELL_MAX_OFFSET+IX_ATM_CELL_PAYLOAD_SIZE)/* * Typedefs */typedef struct { IxAtmConnId connId; IxAtmdAccAalType aalType; UINT32 bytesPerCell; UINT32 atmHeader;} VcInfo;/* * Static variables */static VcInfo ixAtmRxTxTxVcInfoTable[IX_ATM_MAX_NUM_VC];static VcInfo ixAtmRxTxRxVcInfoTable[IX_ATM_MAX_NUM_VC];static IxAtmLogicalPort ixAtmRxTx_port = 0;static UINT32 ixAtmRxTx_vci = IX_ATMCODELET_START_VCI;static UINT32 ixAtmRxTx_vpi = IX_ATMCODELET_START_VPI; static UINT32 ixAtmRxTx_channelIdx = 0;/* Number of VCs configured */static UINT32 ixAtmRxTxNumChannelsConfigured = 0;/* Statistics */static IxAtmCodeletStats *ixAtmRxTxStats = NULL;/* * Function definitions */PRIVATE voidixAtmRxTxStatsReset (void);/* Recieve callback */PRIVATE voidixAtmRxTxRxCallback (IxAtmLogicalPort port, IxAtmdAccUserId userId, IxAtmdAccPduStatus pduStatus, IxAtmdAccClpStatus clp, IX_OSAL_MBUF *mbufPtr);/* Transmit done callback */PRIVATE voidixAtmRxTxTxDoneCallback (IxAtmdAccUserId userId, IX_OSAL_MBUF * mbufPtr);/* Tansmit an Aal5 packet */PRIVATE IX_STATUSixAtmRxTxAal5CpcsTx (IxAtmConnId connId, UINT32 sduLen);/* Tansmit an Aal0 packet */PRIVATE IX_STATUSixAtmRxTxAal0Tx (int channelNum, UINT32 sizeInCells);/* Generic send with retries function */PRIVATE IX_STATUSixAtmRxTxWithRetiesSend (IxAtmConnId connId, IX_OSAL_MBUF* mBuf, UINT32 sizeInCells);/* flush an mbuf from cache (use before sending) */PRIVATE voidixAtmRxTxTxFlush(IX_OSAL_MBUF * mbufPtr);/* invalidate cache (use before reading after rx) */PRIVATE voidixAtmRxTxRxInvalidate(IX_OSAL_MBUF * mbufPtr);PRIVATE IX_STATUSixAtmRxTxAal0PacketBuild (int channelNum, UINT32 sizeInCells, IX_OSAL_MBUF **mBuf);PRIVATE IX_STATUSixAtmRxTxAal5CpcsPduBuild (UINT32 sduLen, IX_OSAL_MBUF **mBuf);/* -------------------------------------------------------------- Initialise the RxTx. -------------------------------------------------------------- */IX_STATUSixAtmRxTxInit (IxAtmCodeletStats *stats){ int i; ixAtmRxTxStats = stats; /* Reset statistics */ ixAtmRxTxStatsReset(); for( i=0; i < IX_ATM_MAX_NUM_VC; i++) { ixAtmRxTxRxVcInfoTable[i].aalType = IX_ATMDACC_MAX_SERVICE_TYPE; ixAtmRxTxTxVcInfoTable[i].aalType = IX_ATMDACC_MAX_SERVICE_TYPE; } return IX_SUCCESS;}/* -------------------------------------------------------------- Get the IxAtmCodeletRxTx counters. -------------------------------------------------------------- */voidixAtmRxTxStatsGet (IxAtmCodeletStats *stats){ *stats = *ixAtmRxTxStats;}/* -------------------------------------------------------------- Remove all provisioned channels. -------------------------------------------------------------- */IX_STATUSixAtmRxTxChannelsRemove ( void ){ IX_STATUS retval; int i; ixAtmRxTx_port = 0; ixAtmRxTx_vci = IX_ATMCODELET_START_VCI; ixAtmRxTx_vpi = IX_ATMCODELET_START_VPI; ixAtmRxTx_channelIdx = 0; retval = ixAtmUtilsAtmAllVcsDisconnect (); if (IX_SUCCESS != retval) { IX_ATMCODELET_LOG ("Failed to remove channels\n"); } for( i=0; i < IX_ATM_MAX_NUM_VC; i++) { ixAtmRxTxRxVcInfoTable[i].aalType = IX_ATMDACC_MAX_SERVICE_TYPE; ixAtmRxTxTxVcInfoTable[i].aalType = IX_ATMDACC_MAX_SERVICE_TYPE; } return retval;}/* -------------------------------------------------------------- Provision channels specifying the number of ports and channels. -------------------------------------------------------------- */IX_STATUSixAtmRxTxChannelsProvision (UINT32 numPorts, UINT32 numChannels, IxAtmdAccAalType aalType){ IX_STATUS retval; UINT32 cellHdr; UINT32 i; IxAtmServiceCategory atmServiceCat = IX_ATM_UBR; /* Set to default */ /* Parameter validation */ if ((numPorts == 0) || (numChannels == 0)) { IX_ATMCODELET_LOG("Invalid parameters to channesls provision \n"); return IX_FAIL; } /* N.B. channelIdx is static */ for (i=0; i < numChannels; i++, ixAtmRxTx_channelIdx++) { /* Save the aalType and bytesPerCell in the Rx & Tx Vc Info tables */ ixAtmRxTxRxVcInfoTable[ixAtmRxTx_channelIdx].aalType = aalType; ixAtmRxTxTxVcInfoTable[ixAtmRxTx_channelIdx].aalType = aalType; if (aalType == IX_ATMDACC_AAL0_52) { ixAtmRxTxTxVcInfoTable[ixAtmRxTx_channelIdx].bytesPerCell = IX_ATM_AAL0_52_CELL_SIZE_NO_HEC; ixAtmRxTxRxVcInfoTable[ixAtmRxTx_channelIdx].bytesPerCell = IX_ATM_AAL0_52_CELL_SIZE_NO_HEC; /* build the cell header for transmission */ cellHdr = (((ixAtmRxTx_vci & 0xFFFF) << 4) | ((ixAtmRxTx_vpi & 0xFF) << 20)); ixAtmRxTxTxVcInfoTable[ixAtmRxTx_channelIdx].atmHeader = cellHdr; ixAtmRxTxRxVcInfoTable[ixAtmRxTx_channelIdx].atmHeader = cellHdr; } else { ixAtmRxTxTxVcInfoTable[ixAtmRxTx_channelIdx].bytesPerCell = IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE; ixAtmRxTxRxVcInfoTable[ixAtmRxTx_channelIdx].bytesPerCell = IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE; } /* Verify whether ATM codelet is going to use Real-time VCs for ( UTOPIA/Remote loopback mode. Otherwise set to UBR VCs by default */ if (ixAtmUtilsAtmRtVcsGet()) { if (IX_ATMCODELET_8VCS > i) { /* 1st 8VCs setup with VBR */ atmServiceCat = IX_ATM_VBR; IX_ATMCODELET_LOG("Setting up VBR: "); } else if ((IX_ATMCODELET_8VCS <= i) && (IX_ATMCODELET_16VCS > i)) { /* 2nd 8VCs setup with CBR */ atmServiceCat = IX_ATM_CBR; IX_ATMCODELET_LOG("Setting up CBR: "); } else { /* Balance is 16 UBR VCs */ atmServiceCat = IX_ATM_UBR; IX_ATMCODELET_LOG("Setting up UBR: "); } } else { IX_ATMCODELET_LOG("Setting up UBR: "); } /* * Register this VC with IxAtmm and connect it to IxAtmdAcc */ retval = ixAtmUtilsAtmVcRegisterConnect(ixAtmRxTx_port, ixAtmRxTx_vpi, ixAtmRxTx_vci, aalType, atmServiceCat, IX_ATM_RX_A, ixAtmRxTxRxCallback, IX_ATMCODELET_RX_FREE_Q_LOW_THRESHOLD, ixAtmRxTxTxDoneCallback, ixAtmRxTxRxFreeLowReplenish, ixAtmRxTx_channelIdx, &ixAtmRxTxRxVcInfoTable[ixAtmRxTx_channelIdx].connId, &ixAtmRxTxTxVcInfoTable[ixAtmRxTx_channelIdx].connId); if (retval != IX_SUCCESS) { IX_ATMCODELET_LOG("VC setup failed for port %2u vpi %3u vci %5u\n", ixAtmRxTx_port, ixAtmRxTx_vpi, ixAtmRxTx_vci); return IX_FAIL; } else { IX_ATMCODELET_LOG("VC configured for port %2u vpi %3u vci %5u\n", ixAtmRxTx_port, ixAtmRxTx_vpi, ixAtmRxTx_vci); } /* Use a different port per channel, depending on the maximum * number of ports configured */ ixAtmRxTx_port++; /* Wrap the port back to 0 when numPorts used already */ if (ixAtmRxTx_port >= (IxAtmLogicalPort)numPorts) { ixAtmRxTx_port = 0; } /* Use the next vci */ ixAtmRxTx_vci++; ixAtmRxTxNumChannelsConfigured++; } return IX_SUCCESS;}/* -------------------------------------------------------------- Send a number of PDUs on the registered channels. -------------------------------------------------------------- */IX_STATUSixAtmRxTxAal0PacketsSend (UINT32 cellsPerPacket, UINT32 numPackets){ UINT32 pktCnt; IX_STATUS retval; BOOL aal0Provisioned = FALSE; UINT32 channelIdx; /* check that there are any Aal0 channels provisioned */ for(channelIdx=0; channelIdx<ixAtmRxTxNumChannelsConfigured; channelIdx++ ) { if ((ixAtmRxTxTxVcInfoTable[channelIdx].aalType == IX_ATMDACC_AAL0_48) || (ixAtmRxTxTxVcInfoTable[channelIdx].aalType == IX_ATMDACC_AAL0_52)) { aal0Provisioned = TRUE; } } if( aal0Provisioned == FALSE ) { IX_ATMCODELET_LOG ("No AAL0 channels are provisioned\n"); return IX_FAIL; } for (pktCnt=0; pktCnt<numPackets;) { /* For each Aal0 VC */ for (channelIdx=0; (pktCnt<numPackets) && (channelIdx<ixAtmRxTxNumChannelsConfigured); channelIdx++ ) { if ((ixAtmRxTxTxVcInfoTable[channelIdx].aalType == IX_ATMDACC_AAL0_48) || (ixAtmRxTxTxVcInfoTable[channelIdx].aalType == IX_ATMDACC_AAL0_52)) { retval = ixAtmRxTxAal0Tx (channelIdx, cellsPerPacket ); if (retval == IX_SUCCESS) { pktCnt++; } else { IX_ATMCODELET_LOG ("Failed to send a pdu on channel...... %u\n", channelIdx); } } } } return IX_SUCCESS; }/* -------------------------------------------------------------- Send a number of PDUs on the registered channels. -------------------------------------------------------------- */IX_STATUSixAtmRxTxAal5CpcsSdusSend (UINT32 sduSize, UINT32 numSdus){ UINT32 sduCnt; IX_STATUS retval; UINT32 channelIdx; BOOL aal5Provisioned = FALSE; /* check that there are any Aal0 channels provisioned */ for(channelIdx=0; channelIdx<ixAtmRxTxNumChannelsConfigured; channelIdx++ ) { if (ixAtmRxTxTxVcInfoTable[channelIdx].aalType == IX_ATMDACC_AAL5) { aal5Provisioned = TRUE; } } if( aal5Provisioned == FALSE ) { IX_ATMCODELET_LOG ("No AAL5 channels are provisioned\n"); return IX_FAIL; } for (sduCnt=0; sduCnt<numSdus;) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -