📄 ixatmdrxtransport.c
字号:
/*** @file ixAtmdRxTransport.c* * @author Intel Corporation* @date 17 March 2002** @brief ATM Rx real time interface*** Design Notes:* This code is real-time critical* * * @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 --*//** Put the user defined include files required.*/#include "IxOsal.h"#include "IxAtmdAccCtrl.h"#include "IxAtmdDefines_p.h"#include "IxAtmdAssert_p.h"#include "IxAtmdUtil_p.h"#define IX_ATMDACC_RX_TRANSPORT_EXTERN#include "IxAtmdRxTransport_p.h"/* function prototype*/PRIVATE INLINE IX_STATUSixAtmdAccRxQueueEntriesGet(IxQMgrQId qMgrQueueId, unsigned int *numberOfEntriesPtr, unsigned int defaultNumberOfEntries);PRIVATE voidixAtmdAccRxProcess (unsigned int physicalAddress);PRIVATE IX_STATUSixAtmdAccRxVcFreeReplenishPossible (IxAtmConnId connId, IX_OSAL_MBUF *mbufPtr, unsigned int * spaceInQmgrQueuePtr);PRIVATE voidixAtmdAccMbufToDescriptorAttach(IxAtmdAccNpeDescriptor *npeDescriptor, IX_OSAL_MBUF *mbufPtr);PRIVATE IX_STATUSixAtmdAccRxVcFreeChainReplenish (IxAtmConnId connId, IX_OSAL_MBUF *mbufPtr);#ifndef NDEBUGPRIVATE voidixAtmdAccRxAckCheck ( unsigned int npeVcId, IxQMgrQId qId );PRIVATE voidixAtmdAccRxPduPtrCheck ( unsigned int physicalAddress, IxQMgrQId qId );#endif/** Function definition.*//* ---------------------------------------------------------* Get the number of entries from a queue and handle the case* where queues are moving during the operation*/PRIVATE INLINE IX_STATUSixAtmdAccRxQueueEntriesGet(IxQMgrQId qMgrQueueId, unsigned int *numberOfEntriesPtr, unsigned int defaultNumberOfEntries){ /* read the number from the queue manager */ IX_STATUS returnStatus = ixQMgrQNumEntriesGet (qMgrQueueId, numberOfEntriesPtr); /* check read success */ if (returnStatus == IX_QMGR_WARNING) { /* read again the number from the queue manager */ returnStatus = ixQMgrQNumEntriesGet (qMgrQueueId, numberOfEntriesPtr); /* cannot get the number of entries : this is because the queue is full */ if (returnStatus == IX_QMGR_WARNING) { /* get the number of entries */ returnStatus = IX_SUCCESS; *numberOfEntriesPtr = defaultNumberOfEntries; } else if (returnStatus != IX_SUCCESS) { /* map the return status */ returnStatus = IX_FAIL; } } /* end of if(returnStatus) */ else if (returnStatus != IX_SUCCESS) { /* map the return status */ returnStatus = IX_FAIL; } return returnStatus;}/* ---------------------------------------------------------* process a shutdown Ack message from NPE*/voidixAtmdAccRxShutdownAck (unsigned int npeVcId){ if (npeVcId < IX_ATM_MAX_NUM_AAL_OAM_RX_VCS) { /* get the VC descriptor */ IxAtmdAccRxVcDescriptor *vcDescriptor = &ixAtmdAccRxVcDescriptor[npeVcId]; if (vcDescriptor->status == IX_ATMDACC_RX_CHANNEL_DOWN_PENDING) { vcDescriptor->status = IX_ATMDACC_RX_CHANNEL_DOWN; } } /* end of if(npeVcId) */ return;}#ifndef NDEBUG/* ---------------------------------------------------------* Check a shutdown Ack message from NPE is arriving from * the right queue*/PRIVATE voidixAtmdAccRxAckCheck (unsigned int npeVcId, IxQMgrQId qId){ IxAtmdAccRxVcDescriptor *vcDescriptor; IX_ATMDACC_ABORT(npeVcId < IX_ATM_MAX_NUM_AAL_OAM_RX_VCS, "npeVcId out of range when receiving a RxShutdownAck"); /* get the VC descriptor */ vcDescriptor = &ixAtmdAccRxVcDescriptor[npeVcId]; IX_ATMDACC_ABORT(qId == vcDescriptor->rxQueueId, "Rx Queue Mismatch when receiving a RxShutdownAck"); return;}/* ------------------------------------------------------------* check a descriptor is from the right queue, check the descriptor order* and check the mbuf chaining*/PRIVATE voidixAtmdAccRxPduPtrCheck (unsigned int physicalAddress, IxQMgrQId qId){ unsigned int connId; unsigned int rxId; IX_OSAL_MBUF *mbufPtr; IX_OSAL_MBUF *tempMbufPtr; IX_OSAL_MBUF *tempMbufPtr2; unsigned int tempHead; IxAtmdAccRxVcDescriptor *vcDescriptor; IX_ATMDACC_RX_QUEUE *rxSwQueue; IxAtmdAccNpeDescriptor *npeDescriptor2; /* incoming traffic descriptor */ IxAtmdAccNpeDescriptor *npeDescriptor = (IxAtmdAccNpeDescriptor *) physicalAddress; IX_ATMDACC_CONVERT_TO_VIRTUAL_ADDRESS (npeDescriptor); /* invalidate the xscale MMU */ IX_ATMDACC_DATA_CACHE_INVALIDATE(npeDescriptor, sizeof(npeDescriptor->npe.rx)); /* check if the signature of the descriptor is still there * If it is not, it means that this is not a valid pointer */ IX_ATMDACC_ABORT(npeDescriptor->atmd.signature == IX_ATMDACC_DESCRIPTOR_SIGNATURE, "Imvalid pointer returned by NPE"); /* get the connection ID in the desriptor fields */ connId = npeDescriptor->atmd.connId; /* get the channel */ rxId = IX_ATMDACC_RX_VC_INDEX_GET (connId); /* get the descriptor */ vcDescriptor = &ixAtmdAccRxVcDescriptor[rxId]; rxSwQueue = &vcDescriptor->queue; IX_ATMDACC_ABORT(qId == vcDescriptor->rxQueueId, "Rx Queue Mismatch"); /* check if the incoming descriptor is the extected descriptor */ if (IX_ATMDACC_RXQ_HEAD_ENTRY_GET (rxSwQueue)->atmd.physicalAddress != physicalAddress) { /* check if we missed a mbuf */ unsigned int count = 0; IX_ATMDACC_FULL_STATS( if (vcDescriptor->status != IX_ATMDACC_RX_CHANNEL_UP) { ixAtmdAccRxTransportErrorStats.descriptorOrderDisconnectErrorCount++; } else { ixAtmdAccRxTransportErrorStats.descriptorOrderErrorCount++; }); /* check the descriptor recycling */ IX_ATMDACC_ABORT (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors queue failure"); do { /* get the mbuf from the descriptor ring buffer */ mbufPtr = IX_ATMDACC_RXQ_HEAD_ENTRY_GET (rxSwQueue)->atmd.pRootMbuf; /* force data to be read from physical memory */ IX_ATMDACC_DATA_CACHE_INVALIDATE(mbufPtr, sizeof(IX_OSAL_MBUF)); /* unchain the mbuf */ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) = NULL; /* return the mbuf the the user */ (*vcDescriptor->rxDoneCallback) (vcDescriptor->port, vcDescriptor->callbackId, IX_ATMDACC_MBUF_RETURN, IX_ATMDACC_CLP_NOT_SET, mbufPtr); /* go forward in the queue */ IX_ATMDACC_RXQ_HEAD_INCR(rxSwQueue); /* check the descriptor recycling */ IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors queue failure"); count++; } while (count < IX_ATMDACC_RXQ_SIZE(rxSwQueue) && IX_ATMDACC_RXQ_HEAD_ENTRY_GET (rxSwQueue)->atmd.physicalAddress != physicalAddress); /* check the descriptor recycling */ IX_ATMDACC_ABORT (IX_ATMDACC_RXQ_HEAD_ENTRY_GET (rxSwQueue)->atmd.physicalAddress == physicalAddress, "Recycling order is wrong"); } /* check all mbufs of a chain are bind to the descriptors of this channel */ tempHead = IX_ATMDACC_SWQ_HEAD(rxSwQueue) ; tempMbufPtr = npeDescriptor->atmd.pRootMbuf; /* check the descriptor recycling */ IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors queue failure"); while (tempMbufPtr) { /* force data to be read from physical memory */ IX_ATMDACC_DATA_CACHE_INVALIDATE(tempMbufPtr, sizeof(IX_OSAL_MBUF)); /* get the mbuf from the descriptor ring buffer */ npeDescriptor2 = IX_ATMDACC_RXQ_ENTRY_IDXGET(rxSwQueue, tempHead); tempMbufPtr2 = npeDescriptor2->atmd.pRootMbuf; /* check the mbuf order is as-expected */ IX_ATMDACC_FULL_STATS( if (tempMbufPtr2 != tempMbufPtr) { ixAtmdAccRxTransportErrorStats.mbufMismatchErrorCount++; }); tempMbufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(tempMbufPtr); if (tempMbufPtr) { IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN (IX_OSAL_MBUF *, tempMbufPtr); IX_ATMDACC_CONVERT_TO_VIRTUAL_ADDRESS (tempMbufPtr); } tempHead = (tempHead + 1) & rxSwQueue->mask; }}#endif/* ------------------------------------------------------------* process a received PDU* free the asscoiated NPE descriptors, and pass the* mbuf/chain up to the user via the supplied callback*/PRIVATE voidixAtmdAccRxProcess (unsigned int physicalAddress){ IX_OSAL_MBUF *mbufPtr; IxAtmdAccPduStatus pduStatus; IxAtmdAccClpStatus clpStatus; UINT32 rxBitField; UINT32 atmCellHeader; unsigned int connId; unsigned int rxId; unsigned int mbufCount; IxAtmdAccRxVcDescriptor *vcDescriptor; IX_ATMDACC_RX_QUEUE *rxSwQueue; /* incoming traffic descriptor */ IxAtmdAccNpeDescriptor *npeDescriptor = (IxAtmdAccNpeDescriptor *) physicalAddress;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -