📄 ixatmdrxtransport.c
字号:
returnStatus = IX_ATMDACC_BUSY; } } } } /* end of if(vcDescriptor) */ return returnStatus;}/* ---------------------------------------------------------* attach a mbuf to a npe descriptor*/PRIVATE voidixAtmdAccMbufToDescriptorAttach(IxAtmdAccNpeDescriptor *npeDescriptor, IX_OSAL_MBUF *mbufPtr){ /* - fill the NPE descriptor fields */ /* - convert the mbuf pointer */ UINT32 rxBitField = npeDescriptor->npe.rx.rxBitField; UINT32 atmCellHeader = npeDescriptor->npe.rx.atmCellHeader; IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN(UINT32, rxBitField); IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN(UINT32, atmCellHeader); IX_NPE_A_ATMCELLHEADER_PTI_SET(atmCellHeader, 0); IX_NPE_A_ATMCELLHEADER_CLP_SET(atmCellHeader, 0); IX_NPE_A_RXBITFIELD_STATUS_SET(rxBitField, NPE_RX_PDU_VALID); npeDescriptor->atmd.pRootMbuf = mbufPtr; npeDescriptor->npe.rx.totalLen = 0; npeDescriptor->npe.rx.pCurrMbuf = mbufPtr; IX_ATMDACC_CONVERT_TO_PHYSICAL_ADDRESS (npeDescriptor->npe.rx.pCurrMbuf); IX_ATMDACC_CONVERT_TO_BIG_ENDIAN (IX_OSAL_MBUF *,npeDescriptor->npe.rx.pCurrMbuf); /* - convert the mbuf header */ /* NPE requires len + 1 */ IX_NPE_A_RXBITFIELD_CURRMBUFSIZE_SET(rxBitField, IX_OSAL_MBUF_MLEN(mbufPtr) + 1); IX_ATMDACC_CONVERT_TO_BIG_ENDIAN(UINT32, rxBitField); npeDescriptor->npe.rx.rxBitField = rxBitField; IX_ATMDACC_CONVERT_TO_PHYSICAL_ADDRESS (IX_OSAL_MBUF_MDATA(mbufPtr)); IX_ATMDACC_CONVERT_TO_BIG_ENDIAN (UINT8 *,IX_OSAL_MBUF_MDATA(mbufPtr)); IX_ATMDACC_CONVERT_TO_BIG_ENDIAN (int,IX_OSAL_MBUF_MLEN(mbufPtr)); npeDescriptor->npe.rx.pCurrMbufData = (unsigned char *)IX_OSAL_MBUF_MDATA(mbufPtr); npeDescriptor->npe.rx.currMbufLen = 0; IX_ATMDACC_CONVERT_TO_BIG_ENDIAN(UINT32, atmCellHeader); npeDescriptor->npe.rx.atmCellHeader = atmCellHeader; npeDescriptor->npe.rx.pNextMbuf = 0; npeDescriptor->npe.rx.aal5CrcResidue = 0xffffffff; /* flush the xscale MMU */ IX_ATMDACC_DATA_CACHE_FLUSH(mbufPtr, sizeof(IX_OSAL_MBUF));}/* ---------------------------------------------------------* send a chain of free buffers to NPE*/PRIVATE IX_STATUSixAtmdAccRxVcFreeChainReplenish (IxAtmConnId connId, IX_OSAL_MBUF *mbufPtr){ IX_STATUS returnStatus; unsigned int spaceInQmgrQueue; IxAtmdAccNpeDescriptor *npeDescriptor; IX_OSAL_MBUF *mbufPtrNext; unsigned int data; /* check parameters and if the Rx free queue has available entruies */ returnStatus = ixAtmdAccRxVcFreeReplenishPossible (connId, mbufPtr, &spaceInQmgrQueue); if (returnStatus == IX_SUCCESS) { /* get the channel */ unsigned int rxId = IX_ATMDACC_RX_VC_INDEX_GET (connId); IxAtmdAccRxVcDescriptor *vcDescriptor = &ixAtmdAccRxVcDescriptor[rxId]; IX_ATMDACC_RX_QUEUE *rxSwQueue = &vcDescriptor->queue; /* indicate that we are replenishInProgress i.e. disconnect is unsafe */ vcDescriptor->replenishInProgress = TRUE; do { /* check if the mbuf length is acceptable */ if (IX_OSAL_MBUF_MLEN(mbufPtr) < vcDescriptor->cellSize) { /* this should not happen to the first mbuf * because it is already checked. The remainder of the mbuf is * returned to the user */ break; } /* check the descriptor queue */ IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors sw queue failure"); npeDescriptor = IX_ATMDACC_RXQ_TAIL_ENTRY_GET (rxSwQueue); IX_ATMDACC_RXQ_TAIL_INCR (rxSwQueue); IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors sw queue failure"); /* save the next mbuf */ mbufPtrNext = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr); IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) = NULL; /* attach an unchained mbuf to a descriptor */ ixAtmdAccMbufToDescriptorAttach(npeDescriptor, mbufPtr); /* flush the xscale MMU */ IX_ATMDACC_DATA_CACHE_FLUSH(npeDescriptor, sizeof(npeDescriptor->npe.rx)); /* store the NPE descriptor in the RX free queue */ data = npeDescriptor->atmd.physicalAddress; returnStatus = ixQMgrQWrite (vcDescriptor->rxFreeQueueId, &data); IX_ATMDACC_ENSURE (returnStatus == IX_SUCCESS, "Qngr status failed"); /* get the next element from the chained list */ mbufPtr = mbufPtrNext; /* iterate until one of the conditions - no buffer chained - rxfree queue is full - no more descriptors are available */ } while (mbufPtr != 0 && returnStatus == IX_SUCCESS && --spaceInQmgrQueue > 0 && !IX_ATMDACC_RXQ_OVERLOADED (rxSwQueue)); /* part of the chanied mbufs are already stored in the RX free queue */ /* the end of the chained mbufs is returned to the client */ if (mbufPtr) { /* pass the end of the chain of mbuf back to the client */ (*vcDescriptor->rxDoneCallback) (vcDescriptor->port, vcDescriptor->callbackId, IX_ATMDACC_MBUF_RETURN, IX_ATMDACC_CLP_NOT_SET, mbufPtr); } /* end of if(mbufPtr) */ vcDescriptor->replenishInProgress = FALSE; } /* end of if(returnStatus) */ return returnStatus;}/* ---------------------------------------------------------* send free buffers to NPE*/IX_STATUSixAtmdAccRxVcFreeReplenish (IxAtmConnId connId, IX_OSAL_MBUF *mbufPtr){ IX_STATUS returnStatus; unsigned int data; IxAtmdAccNpeDescriptor *npeDescriptor; unsigned int rxId = IX_ATMDACC_RX_VC_INDEX_GET (connId); IxAtmdAccRxVcDescriptor *vcDescriptor = &ixAtmdAccRxVcDescriptor[rxId]; IX_ATMDACC_RX_QUEUE *rxSwQueue = &vcDescriptor->queue; IxQMgrQStatus qStatus; IX_ATMDACC_PARAMS_CHECK( if ((vcDescriptor->connId != connId) || (mbufPtr == NULL) || (IX_OSAL_MBUF_MLEN(mbufPtr) < (int) vcDescriptor->cellSize)) { return IX_FAIL; }); /* check for queue full */ returnStatus = ixQMgrQStatusGet(vcDescriptor->rxFreeQueueId, &qStatus); if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK) { /* the rxfree queue is full */ return IX_ATMDACC_BUSY; } /* happy day scenario : check for unchained mbufs */ if ((IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) == NULL) && (!IX_ATMDACC_RXQ_OVERLOADED (rxSwQueue)) ) { vcDescriptor->replenishInProgress = TRUE; /* check the descriptor queue */ IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors sw queue failure"); npeDescriptor = IX_ATMDACC_RXQ_TAIL_ENTRY_GET (rxSwQueue); IX_ATMDACC_RXQ_TAIL_INCR (rxSwQueue); IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors sw queue failure"); /* attach an unchained mbuf to a descriptor */ ixAtmdAccMbufToDescriptorAttach(npeDescriptor, mbufPtr); /* store the NPE descriptor in the RX free queue */ data = npeDescriptor->atmd.physicalAddress; /* flush the xscale MMU */ IX_ATMDACC_DATA_CACHE_FLUSH(npeDescriptor, sizeof(npeDescriptor->npe.rx)); returnStatus = ixQMgrQWrite (vcDescriptor->rxFreeQueueId, &data); if (returnStatus != IX_SUCCESS) { /* roll back */ IX_ATMDACC_RXQ_TAIL_DECR (rxSwQueue); /* check unreachable conditions */ IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors sw queue failure"); /* roll back the mbuf */ IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN (UINT8 *, IX_OSAL_MBUF_MDATA(mbufPtr)); IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN (int, IX_OSAL_MBUF_MLEN(mbufPtr)); IX_ATMDACC_CONVERT_TO_VIRTUAL_ADDRESS (IX_OSAL_MBUF_MDATA(mbufPtr)); /* map the error status */ if (returnStatus == IX_QMGR_Q_OVERFLOW) { returnStatus = IX_ATMDACC_BUSY; } else { returnStatus = IX_FAIL; } } vcDescriptor->replenishInProgress = FALSE; } else { /* something is not "happy day" scenario : * this can be chained mbufs, sw queue full */ returnStatus = ixAtmdAccRxVcFreeChainReplenish (connId, mbufPtr); } /* end of if(returnStatus) */ /* return the status to the client */ return returnStatus;}/* ---------------------------------------------------------* QMgr callback for rx free events*/voidixAtmdAccRxFreeCallback (IxQMgrQId qId, IxQMgrCallbackId cbId){ IxAtmdAccRxVcDescriptor *vcDescriptor; /* check callback values and unreachable conditions */ IX_ATMDACC_ENSURE (IX_ATMDACC_RX_FREEQ_ID_VALID (qId), "Qmgr invalid qId"); IX_ATMDACC_ENSURE (IX_ATMDACC_RX_FREECALLBACK_ID_VALID (cbId), "Qmgr invalid callback Id"); /* the channel id is the callback userid */ vcDescriptor = &ixAtmdAccRxVcDescriptor[cbId]; /* check callback pointer */ IX_ATMDACC_ENSURE (vcDescriptor->rxFreeNotification != NULL, "Invalid callback pointer"); /* invoke the user callback */ (*vcDescriptor->rxFreeNotification) (vcDescriptor->callbackId);}/* ---------------------------------------------------------* get the number of free entries in the RX Free queue*/PUBLIC IX_STATUSixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId, unsigned int *numberOfMbufsPtr){ IX_STATUS returnStatus; unsigned int rxId; unsigned int numberOfEntries; IxAtmdAccRxVcDescriptor *vcDescriptor; /* get the channel for this connId */ rxId = IX_ATMDACC_RX_VC_INDEX_GET (connId); vcDescriptor = &ixAtmdAccRxVcDescriptor[rxId]; /* check the connextion Id */ if ((vcDescriptor->connId != connId) || (numberOfMbufsPtr == NULL)) { returnStatus = IX_FAIL; } else { /* check unreachable conditions */ IX_ATMDACC_ENSURE (IX_ATMDACC_RX_VC_INUSE (vcDescriptor->connId), "Invalid conn ID"); /* read the number from the queue manager */ returnStatus = ixAtmdAccRxQueueEntriesGet(vcDescriptor->rxFreeQueueId, &numberOfEntries, 0); /* check the qmgr status */ IX_ATMDACC_ENSURE (returnStatus == IX_SUCCESS, "Qngr status failed"); /* map the qmgr error code */ if (returnStatus == IX_SUCCESS) { *numberOfMbufsPtr = vcDescriptor->rxFreeQueueSize - numberOfEntries; } /* end of if-else(returnStatus) */ } /* end of if-else(vcDescriptor) */ return returnStatus;}/* --------------------------------------------------------- * get the number of used entries in the RX queue */PUBLIC IX_STATUSixAtmdAccRxLevelQuery (IxAtmRxQueueId atmdQueueId, unsigned int *numberOfPdusPtr){ IX_STATUS returnStatus; IxQMgrQId qMgrQueueId; /* check parameters */ if (numberOfPdusPtr == NULL) { returnStatus = IX_FAIL; } else { /* convert qIds amd check input parameter */ returnStatus = ixAtmdAccUtilQmgrQIdGet (atmdQueueId, &qMgrQueueId); } /* end of if-else(numberOfPdusPtr) */ if (returnStatus == IX_SUCCESS) { /* read the number from the queue manager */ returnStatus = ixAtmdAccRxQueueEntriesGet (qMgrQueueId, numberOfPdusPtr, IX_QMGR_Q_SIZE64); } /* end of if(returnStatus) */ return returnStatus;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -