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

📄 ixatmdtxtransport.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (returnStatus != IX_SUCCESS)    {        /* update stats */        ixAtmdAccTxDoneDispatchStats.failedCount++;    }    else    {        /* update stats */        if (txDoneCount > ixAtmdAccTxDoneDispatchStats.maxPduPerDispatch)        {            ixAtmdAccTxDoneDispatchStats.maxPduPerDispatch = txDoneCount;        }    });    return returnStatus;}/* ----------------------------------------------------------* Return the level of the Tx done queue*/PUBLIC IX_STATUSixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr){    IX_STATUS returnStatus = IX_SUCCESS;    /* check for null pointer */    if (numberOfPdusPtr == NULL)    {        returnStatus = IX_FAIL;    }    else    {        /* get the number of entries from the Q manager */        returnStatus = ixAtmdAccTxQueueEntriesGet (IX_NPE_A_QMQ_ATM_TX_DONE,            numberOfPdusPtr,            IX_ATMDACC_TXDONE_QUEUE_SIZE);    } /* end of if-else(numberOfPdusPtr) */    return returnStatus;}/* ----------------------------------------------------* notify the user that the tx done queue level is high*/voidixAtmdAccTxDoneCallBack (IxQMgrQId qId,			 IxQMgrCallbackId cbId)                         {#ifndef __wince    IX_STATUS status;#endif    unsigned int numberOfPdus = IX_ATMDACC_ALLPDUS;    unsigned int numberOfPdusProcessed = 0;    /* WINCE_PORT NOTE: function pointer comparison across DLLs does not work. */#ifndef __wince    /* if the callback is not the internal dispatcher function    * get the number of entries from the queue    */    if(ixAtmdAccTxDoneDispatcher != ixAtmdAccTxDoneDispatch)    {        status = ixAtmdAccTxQueueEntriesGet (IX_NPE_A_QMQ_ATM_TX_DONE,             &numberOfPdus,            IX_ATMDACC_TXDONE_QUEUE_SIZE);        /* no way to continue if the status is not success */        IX_ATMDACC_ABORT(status == IX_SUCCESS, "TxDoneCallBack ixAtmdAccTxQueueEntriesGet failed");    }#endif    /* process all entries from the queue */    (*ixAtmdAccTxDoneDispatcher) (numberOfPdus, &numberOfPdusProcessed);}/* -------------------------------------------------------* Submit a PDU for transmission*/PUBLIC IX_STATUSixAtmdAccTxVcPduSubmit (IxAtmConnId connId,                        IX_OSAL_MBUF* mbufPtr,                        IxAtmdAccClpStatus clp,                        unsigned int numberOfCells){    IX_STATUS status;    UINT32 atmCellHeader;    IxAtmdAccNpeDescriptor  *npeDescriptor;    IxAtmdAccPortDescriptor *portDescriptor;    IxAtmdAccTxVcDescriptor *vcDescriptor;    IX_STATUS returnStatus = IX_SUCCESS;    IX_ATMDACC_TX_QUEUE *txSwQueue;    unsigned int descriptorIndex = IX_ATMDACC_TX_VC_INDEX_GET (connId);    vcDescriptor = &ixAtmdAccTxVcDescriptor[descriptorIndex];    /* indicate that a PDU transmit is in progress    * i.e. not safe to disconnect    */        vcDescriptor->pduTransmitInProgress = TRUE;    /* sanity check the parameters, includes a check to ensure    * that a disconnecting or obsolete connId are rejected    */    IX_ATMDACC_PARAMS_CHECK(    if ((vcDescriptor->connId != connId)                                       ||        (mbufPtr == NULL)                                                      ||        (numberOfCells == 0)                                                   ||        ((unsigned int)IX_OSAL_MBUF_MLEN(mbufPtr) == 0)                            ||        ((unsigned int)IX_OSAL_MBUF_PKT_LEN(mbufPtr) > IX_ATMDACC_MAX_PDU_LEN)       ||        ((unsigned int)IX_OSAL_MBUF_PKT_LEN(mbufPtr) != numberOfCells * vcDescriptor->cellSize) ||        ((clp != IX_ATMDACC_CLP_SET) && (clp != IX_ATMDACC_CLP_NOT_SET)))    {        /* param check failed */        IX_ATMDACC_FULL_STATS(        if(vcDescriptor->connId == connId)        {   /* increment the stats of the correct channel */            vcDescriptor->txVcPduSubmitFailureCount++;        });        vcDescriptor->pduTransmitInProgress = FALSE;        return IX_FAIL;    });    /* extract the VC descriptor pool index from the connId    * and get the descriptor    */    txSwQueue = &vcDescriptor->queue;        /* check the state of the tx queue */    IX_ATMDACC_ENSURE (IX_ATMDACC_TXQ_CONSISTENT (txSwQueue), "corrupted sw tx queue");        /* get a recycled descriptor */    if (!IX_ATMDACC_TXQ_OVERLOADED (txSwQueue))    {    /* indicate that a PDU transmit is in progress    * i.e. not safe to disconnect        */                /* get the current descriptor from the tx sw queue */        npeDescriptor = IX_ATMDACC_TXQ_MID_ENTRY_GET (txSwQueue);                /* get a port descriptor for this port */        portDescriptor = &ixAtmdAccPortDescriptor[vcDescriptor->port];                /* convert the mbuf/chain to Npe (physical) address, and        * big endian format        */            npeDescriptor->atmd.pRootMbuf = mbufPtr;            npeDescriptor->atmd.totalCell = numberOfCells;            /* fill the NPE descriptor fields */            atmCellHeader = npeDescriptor->npe.tx.atmCellHeader;            IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN(UINT32, atmCellHeader);            IX_NPE_A_ATMCELLHEADER_PTI_SET(atmCellHeader, 0);            IX_NPE_A_ATMCELLHEADER_CLP_SET(atmCellHeader, clp);            IX_ATMDACC_CONVERT_TO_BIG_ENDIAN(UINT32, atmCellHeader);            npeDescriptor->npe.tx.atmCellHeader = atmCellHeader;             npeDescriptor->npe.tx.totalLen = IX_OSAL_MBUF_PKT_LEN(mbufPtr);            npeDescriptor->npe.tx.currMbufLen = IX_OSAL_MBUF_MLEN(mbufPtr);            IX_ATMDACC_CONVERT_TO_BIG_ENDIAN (UINT32, npeDescriptor->npe.tx.totalLen);            IX_ATMDACC_CONVERT_TO_BIG_ENDIAN16 (npeDescriptor->npe.tx.currMbufLen);            npeDescriptor->npe.tx.pCurrMbuf = ixAtmdAccUtilMbufToNpeFormatConvert (mbufPtr);            npeDescriptor->npe.tx.pCurrMbufData = (unsigned char *)IX_OSAL_MBUF_MDATA(mbufPtr);            npeDescriptor->npe.tx.pNextMbuf = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbufPtr);            npeDescriptor->npe.tx.aal5CrcResidue = 0xffffffff;            /* flush the xscale MMU */            IX_ATMDACC_DATA_CACHE_FLUSH(npeDescriptor, sizeof(npeDescriptor->npe.tx));            /* store the pdu in a sw queue */            IX_ATMDACC_TXQ_MID_INCR (txSwQueue);            /* check unreachable conditions */            IX_ATMDACC_ENSURE (IX_ATMDACC_TXQ_CONSISTENT (txSwQueue), "corrupted sw tx queue");            /* submit this request to the scheduler */            status = (*(portDescriptor->schDemandUpdate)) (vcDescriptor->port,                vcDescriptor->schedulerVcId,                numberOfCells);            switch (status)            {            case IX_SUCCESS:                break;            case IX_FAIL:            case IX_ATMDACC_BUSY:            /* If scheduler fails to accept this request we may need to roll back */            /* perform a full rollback : remove the PDU from the queue */            IX_ATMDACC_TXQ_MID_DECR (txSwQueue);            /* if the sw queue is in a bad state, this is because there is over scheduling            * during a channelUpdate failure (double failure from the scheduler). In this            * situation, there is no possible recovery.            */            IX_ATMDACC_ABORT (IX_ATMDACC_TXQ_CONSISTENT (txSwQueue),                "corrupted sw tx queue (overscheduling detected)");                        /* convert back to logical address for the user domain */            ixAtmdAccUtilMbufFromNpeFormatConvert (mbufPtr, FALSE);                        /* update stats */            IX_ATMDACC_FULL_STATS( vcDescriptor->txSubmitOverloadedCount++);            /* no descriptor available */            returnStatus = IX_ATMDACC_BUSY;            break;            default:            /* any other kind of failure we dont roll back             * because the NPE may have started to operate on             * the PDU             */            IX_ATMDACC_ABORT(0, "ixAtmdAccTxPduSubmit non recoverable scheduling entity error");            break;        } /* end of switch(status) */    } /* end of if(IX_ATMDACC_TXQ_OVERLOADED) */    else    {        /* update stats */        IX_ATMDACC_FULL_STATS( vcDescriptor->txSubmitOverloadedCount++; );                /* no descriptor available */        returnStatus = IX_ATMDACC_BUSY;    } /* end of if-else(IX_ATMDACC_TXQ_OVERLOADED) */   /* indicate that a PDU transmission is complete    * i.e. safe to disconnect now    */        vcDescriptor->pduTransmitInProgress = FALSE;    return returnStatus;}/* -----------------------------------------------------------*        transmit the specified number of cells emediately,*        behaves like a dummy scheduler*/IX_STATUSixAtmdAccTxDummyDemandUpdate (IxAtmLogicalPort port,                              int vcId,                              unsigned int numberOfCells){    IxAtmdAccTxVcDescriptor *vcDescriptor;    IxAtmdAccNpeDescriptor *npeDescriptor;    IxAtmdAccPortDescriptor *portDescriptor;    IX_ATMDACC_TX_QUEUE *txSwQueue;    unsigned int numFreeEntries;    unsigned int numEntries;    unsigned int numEntriesReqd;    unsigned int descriptorIndex;    IX_STATUS returnStatus;    UINT32 *qMgrEntryPtr;    portDescriptor = &ixAtmdAccPortDescriptor[port];    /* ixAtmdAccTxUnscheduledModeVcIdGet ensures that VcId is a descriptorIndex */    descriptorIndex = vcId;    vcDescriptor = &ixAtmdAccTxVcDescriptor[descriptorIndex];    txSwQueue = &vcDescriptor->queue;    /* check the number of entries in the queue */    returnStatus = ixAtmdAccTxQueueEntriesGet (portDescriptor->txQueueId,        &numEntries,         0);    if (returnStatus == IX_SUCCESS)    {        /* compute the number of free entries in the TX queue */        numFreeEntries = portDescriptor->txQueueSize - (unsigned int) numEntries;        /* compute the number of free entries required by the current demand */        numEntriesReqd = (numberOfCells + (NPE_TX_MAXCELLS_PER_QENTRY - 1)) / NPE_TX_MAXCELLS_PER_QENTRY;        /* compare the available queue level and the requested number of        entries requested */        if (numFreeEntries < numEntriesReqd)        {            /* cannot put all the PDU in the TX queue */            returnStatus = IX_ATMDACC_BUSY;        }    } /* end of if(returnStatus) */    if (returnStatus == IX_SUCCESS)    {        /* check unreachable conditions */        IX_ATMDACC_ENSURE (IX_ATMDACC_TXQ_CONSISTENT (txSwQueue), "corrupted sw tx queue");        /* check that there is something in the queue to schedule */        IX_ATMDACC_ENSURE (IX_ATMDACC_TXQ_SCHEDULE_PENDING (txSwQueue), "corrupted sw tx queue");        /* get the the descriptor from the tx queue */        npeDescriptor = IX_ATMDACC_TXQ_TAIL_ENTRY_GET (txSwQueue);        IX_ATMDACC_TXQ_TAIL_INCR (txSwQueue);        /* check unreachable conditions */        IX_ATMDACC_ENSURE (IX_ATMDACC_TXQ_CONSISTENT (txSwQueue), "corrupted sw tx queue");        /* check that everything in the queue has been scheduled */        IX_ATMDACC_ENSURE (!IX_ATMDACC_TXQ_SCHEDULE_PENDING (txSwQueue), "corrupted sw tx queue");        qMgrEntryPtr = portDescriptor->qMgrEntries;         /* transmit all Cells from the current PDU */        ixAtmdAccCellTx (&qMgrEntryPtr,            npeDescriptor->atmd.physicalAddress,            (unsigned int) numberOfCells,            NPE_TX_DATACELL);        /* get the number of entries by a pointer substraction and        * burst write all entries if no error found before         */        returnStatus = ixQMgrQBurstWrite (portDescriptor->txQueueId,             qMgrEntryPtr - portDescriptor->qMgrEntries,             portDescriptor->qMgrEntries);        if (returnStatus != IX_SUCCESS)        {            returnStatus = IX_FAIL;        }                /* update stats */        IX_ATMDACC_FULL_STATS(            ixAtmdAccTxTransportStats[port].dataCellScheduledCount +=            numberOfCells; );    } /* end of if(returnStatus) */    return returnStatus;}

⌨️ 快捷键说明

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