⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ixatmdrxtransport.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 3 页
字号:
    IX_ATMDACC_CONVERT_TO_VIRTUAL_ADDRESS (npeDescriptor);    /* invalidate the xscale MMU */    IX_ATMDACC_DATA_CACHE_INVALIDATE(npeDescriptor, sizeof(npeDescriptor->npe.rx));    IX_ATMD_DEBUG_DO(    /* 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;    /* check the descriptor recycling */    IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue),         "Rx descriptors queue failure");            /* check the descriptor recycling is exact : no descriptor is missing */    IX_ATMDACC_ABORT (IX_ATMDACC_RXQ_HEAD_ENTRY_GET (rxSwQueue)->atmd.physicalAddress		      == physicalAddress, "Descriptor Recycling order is wrong");        /* get the PDU length information */    IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN (UINT32, npeDescriptor->npe.rx.totalLen);    /* get the mbuf pointer and process the endianness     * and update the pkt header field, and the length of the last mbuf    */    mbufPtr = ixAtmdAccUtilRxMbufFromNpeFormatConvert (        npeDescriptor->atmd.pRootMbuf,        npeDescriptor->npe.rx.totalLen,        &mbufCount);    IX_ATMDACC_ENSURE((vcDescriptor->npeAalType == NPE_AAL5_TYPE) ||                      ((vcDescriptor->npeAalType != NPE_AAL5_TYPE) && 		      (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr) == NULL)),                     "Rx PDU has illegal chain on AAL0/OAM");    IX_ATMDACC_ENSURE(((vcDescriptor->npeAalType == NPE_OAM_TYPE) &&                        (npeDescriptor->npe.rx.totalLen == vcDescriptor->cellSize)) ||                      ((vcDescriptor->npeAalType != NPE_OAM_TYPE) &&                        ((npeDescriptor->npe.rx.totalLen % vcDescriptor->cellSize) == 0)),                    "Rx PDU has incomplete cells (AALx) or multiple cells (OAM)");     rxBitField = npeDescriptor->npe.rx.rxBitField;     IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN(UINT32, rxBitField);     atmCellHeader = npeDescriptor->npe.rx.atmCellHeader;     IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN(UINT32, atmCellHeader);    /* check the channel + connId validity */    if (vcDescriptor->connId == connId)    {        /* the connId is valid */        /* get the PDU informations : status */        if (IX_NPE_A_RXBITFIELD_STATUS_GET(rxBitField)            == NPE_RX_PDU_VALID)        {            pduStatus = vcDescriptor->pduValidStatusCode;        }        else        {            pduStatus = vcDescriptor->pduInvalidStatusCode;        } /* end of if-else(npeDescriptor) */        clpStatus = IX_NPE_A_ATMCELLHEADER_CLP_GET(atmCellHeader);        /* recycle the descriptors */        IX_ATMDACC_RXQ_HEAD_ADVANCE (rxSwQueue, mbufCount);        /* check the descriptor queue */        IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors queue failure");        /* call the receive event for this channel id */        vcDescriptor->rxDoneCallback (            IX_NPE_A_RXBITFIELD_PORT_GET(rxBitField),            vcDescriptor->callbackId,             pduStatus,             clpStatus,             mbufPtr);    }    else    {        /* this descriptor is related to something old and already disconnected */        IX_ATMDACC_RXQ_HEAD_ADVANCE (rxSwQueue, mbufCount);                /* check the descriptor queue */        IX_ATMDACC_ENSURE (IX_ATMDACC_RXQ_CONSISTENT (rxSwQueue), "Rx descriptors queue failure");                /* release the buffer */        (*vcDescriptor->rxDoneCallback) (vcDescriptor->port,            vcDescriptor->callbackId,            IX_ATMDACC_MBUF_RETURN,            IX_ATMDACC_CLP_NOT_SET,            mbufPtr);    } /* end of if-else(vcDescriptor) */}/* ---------------------------------------------------------* process the entries from the RX queue*/PUBLIC IX_STATUSixAtmdAccRxDispatch (IxAtmRxQueueId atmdQueueId,                     unsigned int numberOfPdusToProcess,                     unsigned int *numberOfPdusProcessedPtr){    IX_STATUS returnStatus = IX_SUCCESS;    IX_STATUS qmgrStatus = IX_SUCCESS;    IxQMgrQId qId;    UINT32 *qEntryPtr;    UINT32 qEntry;    UINT32 numberOfEntriesToRead;    IX_ATMDACC_FULL_STATS( unsigned totalRx = 0; );    /* check the parameters */    IX_ATMDACC_PARAMS_CHECK(    if ((numberOfPdusProcessedPtr == NULL) ||        (numberOfPdusToProcess == 0)       ||        (ixAtmdAccUtilQmgrQIdGet (atmdQueueId, &qId) != IX_SUCCESS) ||        (qId != ixAtmdAccRxQMgrQId[atmdQueueId]))    {        /* param check failed */        IX_ATMDACC_FULL_STATS(        if(atmdQueueId < IX_ATM_MAX_RX_STREAMS)        {            ixAtmdAccRxDispatchStats[atmdQueueId].failedCount++;         });        return IX_FAIL;    });    /* get the qId from a stream table      * this overwrites the qId that was returned if param checks are enabled     * but done this way for performance when they are not enabled     */    qId = ixAtmdAccRxQMgrQId[atmdQueueId];    /* update stats */    IX_ATMDACC_FULL_STATS( ixAtmdAccRxDispatchStats[atmdQueueId].invokeCount++; );        /* initialise the result parameter */    *numberOfPdusProcessedPtr = 0;        /* iterate until all entries requested are processed */    do    {        /* set the pointer to the beginning of the buffer */        qEntryPtr = ixAtmdAccRxQMgrBuffer[atmdQueueId];                /* get the number of entries to read */        if (numberOfPdusToProcess >= IX_ATMDACC_RX_QUEUE_SIZE)        {            numberOfEntriesToRead = IX_ATMDACC_RX_QUEUE_SIZE;        }        else        {            numberOfEntriesToRead = numberOfPdusToProcess;            qEntryPtr[numberOfEntriesToRead] = 0;        }                /* read all the queue entries (note that the buffer size is adjusted         * and initialised to ensure that there is always a null entry        * at the end of the buffer. This code assume that a null entry         * is stored by qMgr at the end of the input data.        */        qmgrStatus = ixQMgrQBurstRead (qId,             numberOfEntriesToRead,             qEntryPtr);                /* get the first entry from the buffer */        qEntry = *qEntryPtr;        /* iterate through all entries until a null entry is found */        while (qEntry != 0)        {            /* check the queue entry type */            switch(qEntry & NPE_RX_TYPE_MASK)            {            case NPE_RX_DESCRIPTOR:                IX_ATMD_DEBUG_DO(                /* check the descriptor is from the right queue                * and check the descriptor order is valid, and mbuf                * chaining is correct, and try to recover if it                * is possible to recover, and update statistics.                */                ixAtmdAccRxPduPtrCheck(qEntry & NPE_DESCRIPTOR_MASK, qId)                );                                /* process data descriptor */                ixAtmdAccRxProcess (qEntry & NPE_DESCRIPTOR_MASK);                                /* update stats */                IX_ATMDACC_FULL_STATS(                     totalRx++;                    ixAtmdAccRxDispatchStats[atmdQueueId].spPduCount++; );                                /* update the number of pdu processed */                numberOfPdusToProcess--;                (*numberOfPdusProcessedPtr)++;                break;            case NPE_RX_SHUTDOWN_ACK:                IX_ATMD_DEBUG_DO(                    /* check the descriptor ack is from the right queue */                    ixAtmdAccRxAckCheck((qEntry & NPE_RX_SHUTDOWN_ACK_VCID_MASK) >> NPE_SHUTDOWN_ACK_SHIFT, qId);                );                /* process rx shutdown ack */                ixAtmdAccRxShutdownAck ((unsigned int) ((qEntry & NPE_RX_SHUTDOWN_ACK_VCID_MASK) >> NPE_SHUTDOWN_ACK_SHIFT));                                /* update stats */                IX_ATMDACC_FULL_STATS( ixAtmdAccRxDispatchStats[atmdQueueId].ackCount++; );                break;            default:                /* update stats */                IX_ATMDACC_FULL_STATS( ixAtmdAccRxDispatchStats[atmdQueueId].invalidDescCount++; );                returnStatus = IX_FAIL;                break;            }                        /* get the next entry from the buffer */            qEntry = *(++qEntryPtr);        } /* end of while(qEntry) */    }    while ((qmgrStatus == IX_SUCCESS) && (numberOfPdusToProcess > 0));    IX_ATMDACC_FULL_STATS(    if (totalRx > ixAtmdAccRxDispatchStats[atmdQueueId].maxRxPerDispatch)    {        ixAtmdAccRxDispatchStats[atmdQueueId].maxRxPerDispatch = totalRx;        if (returnStatus != IX_SUCCESS)        {            ixAtmdAccRxDispatchStats[atmdQueueId].failedCount++;         }    });    return returnStatus;}/* ---------------------------------------------------------* queue manager callback to be used to receive data from NPE*/voidixAtmdAccRxCallback (IxQMgrQId qMgrQueueId,                     IxQMgrCallbackId cbId){    unsigned int dummynumberOfPdusProcessed;    unsigned int numberOfPdusToProcess = IX_ATMDACC_ALLPDUS;#ifndef __wince    IX_STATUS returnStatus;#endif    /* check queueId and callbackId values */    IX_ATMDACC_ENSURE (IX_ATMDACC_RX_VCQ_ID_VALID (qMgrQueueId), "Qmgr invalid qId");    IX_ATMDACC_ENSURE (IX_ATMDACC_RX_CALLBACK_ID_VALID (cbId), "Qmgr invalid callback Id");    /* WINCE_PORT NOTE: function pointer comparison across DLLs does not work. */#ifndef __wince    /* check the registered callback : if it is the atmdAcc callback, there    * is no need to read the qmgr level, because the action will be    * to process all pdus.    */    if (ixAtmdAccRxUserCallback[cbId] != ixAtmdAccRxDispatch)    {        returnStatus = ixAtmdAccRxQueueEntriesGet(qMgrQueueId,            &numberOfPdusToProcess,            IX_QMGR_Q_SIZE64);        /* check the qmgr status : should not fail */        IX_ATMDACC_ABORT (returnStatus == IX_SUCCESS, "Qngr status failed");        if (numberOfPdusToProcess == 0)        {            /* nothing to process in this queue */            return;        }    } /* end of if(ixAtmdAccRxUserCallback) */#endif    /* invoke the user callback */    (*ixAtmdAccRxUserCallback[cbId]) ((IxAtmRxQueueId) cbId,        numberOfPdusToProcess,        &dummynumberOfPdusProcessed);}/* ---------------------------------------------------------*/PRIVATE IX_STATUSixAtmdAccRxVcFreeReplenishPossible (IxAtmConnId connId,                                    IX_OSAL_MBUF *mbufPtr,                                    unsigned int * spaceInQmgrQueuePtr){    IX_STATUS returnStatus = IX_SUCCESS;    unsigned int numEntriesInQmgrQueue;    /* get the channel */    unsigned int rxId = IX_ATMDACC_RX_VC_INDEX_GET (connId);    IxAtmdAccRxVcDescriptor *vcDescriptor = &ixAtmdAccRxVcDescriptor[rxId];    IX_ATMDACC_RX_QUEUE *rxSwQueue = &vcDescriptor->queue;        /* check parameters */    if ((vcDescriptor->connId != connId) ||        (mbufPtr == NULL)                ||        (IX_OSAL_MBUF_MLEN(mbufPtr) < vcDescriptor->cellSize)        )    {        returnStatus = IX_FAIL;    }    else    {        /* check if a descriptor is available */        if (IX_ATMDACC_RXQ_OVERLOADED (rxSwQueue))        {            returnStatus = IX_ATMDACC_BUSY;        }        else        {            returnStatus = ixAtmdAccRxQueueEntriesGet(vcDescriptor->rxFreeQueueId,                &numEntriesInQmgrQueue,                0);                        IX_ATMDACC_ENSURE (returnStatus == IX_SUCCESS, "Qngr status failed");                        /* map the qmgr error code */            if (returnStatus == IX_SUCCESS)            {                *spaceInQmgrQueuePtr = vcDescriptor->rxFreeQueueSize - numEntriesInQmgrQueue;                                /* check the queue is full */                if (*spaceInQmgrQueuePtr == 0)                {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -