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

📄 ixatmdtxtransport.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 4 页
字号:
/*** @file IxAtmdTxTransport.c* * @author Intel Corporation* @date 17 March 2002** @brief ATM Tx real time interface**        This module implements the transmit data path part*        of Atmd. It provides public interfaces that enable*        the user to submit and schedule PDUs for transmission,*        and to control the re-cycling of the resources belonging to*        transmitted PDUs.** 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"#include "IxAtmdTxCfgInfo_p.h"#define IX_ATMDACC_TX_TRANSPORT_EXTERN#include "IxAtmdTxTransport_p.h"/* function prototype */PRIVATE INLINE IX_STATUSixAtmdAccTxQueueEntriesGet(IxQMgrQId qMgrQueueId,                           unsigned int *numberOfEntriesPtr,                           unsigned int defaultNumberOfEntries);PRIVATE INLINE IX_STATUSixAtmdAccTxQFreeEntriesQuery (IxAtmLogicalPort port,                              unsigned int *numberOfCellsPtr);PRIVATE INLINE UINT32ixAtmdAccTxQueueEntryBuild (unsigned int physicalAddress,                            unsigned int cellCount,                            unsigned int cellType);/* Remove INLINE keyword to resolve cannot inline warning (Linux). SCR1421 */PRIVATE voidixAtmdAccCellTx (UINT32 **qMgrEntryPtr,                 unsigned int physicalAddress,                 unsigned int cellCount,                 unsigned int cellType);/* Remove INLINE keyword to resolve cannot inline warning (Linux). SCR1421 */PRIVATE voidixAtmdAccChannelTx (UINT32 **qMgrEntryPtr,                    IxAtmdAccTxVcDescriptor * vcDescriptor,                    unsigned int cellCount);PRIVATE voidixAtmdAccTxScheduleProcess (UINT32 **qMgrEntryPtr,                            IxAtmScheduleTableEntry *scheduleTableEntryPtr,                            unsigned int lastScheduleTableEntry);PRIVATE voidixAtmdAccTxDoneProcess (unsigned int physicalAddress);PRIVATE voidixAtmdAccTxShutdownAck (IxAtmLogicalPort port);/** Function definition.*//* ---------------------------------------------------------* Get the number of entries from a queue and handle the case* where queues are moving during the operation*/PRIVATE INLINE IX_STATUSixAtmdAccTxQueueEntriesGet(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;}/* ---------------------------------------------------------*        Return the number of free entries in the transmit*        queue for this port*/PRIVATE INLINE IX_STATUSixAtmdAccTxQFreeEntriesQuery (IxAtmLogicalPort port,                              unsigned int *numberOfCellsPtr){    unsigned int numEntries;    IxAtmdAccPortDescriptor  *portDescriptor;    IX_STATUS returnStatus = IX_SUCCESS;    portDescriptor = &ixAtmdAccPortDescriptor[port];    /* get the current number of entries */    returnStatus = ixAtmdAccTxQueueEntriesGet (portDescriptor->txQueueId,        &numEntries,        0);    /* map the return status */    if (returnStatus != IX_SUCCESS)    {        returnStatus = IX_FAIL;    }        *numberOfCellsPtr = portDescriptor->txQueueSize - numEntries;    return returnStatus;}/* ---------------------------------------------------------* Write a queue entry to the qmgr tx queue*/PRIVATE INLINE UINT32ixAtmdAccTxQueueEntryBuild (unsigned int physicalAddress,                            unsigned int cellCount,                            unsigned int cellType){    /* build a tx queue entry     * For Data Cells    *  - MSB 31-6 : descriptor physical address    *  - bits 5-2 : number of cells    *  - bits 1 : set to 0 (reserved)    *  - bit 0 : set to 0 (flag data cell )    * For Idle Cells    *  - MSB 31-6 : 0    *  - bits 5-2 : number of cells    *  - bits 1 : set to 0 (reserved)    *  - bit 0 : set to 0 (flag idle cell )    */        UINT32 qEntry = (cellCount << NPE_TX_CELLCOUNT_OFFSET) | physicalAddress | cellType;    return qEntry;}/* ---------------------------------------------------------*  Convert the requested number of cells to queue entries for NPE-A**  qMgrEntryPtr is a pointer to an internal array of entries*               This array, when ready, will be flushed by the qMgr*  physicalAddress : physical address of a NPE descriptor which is*               bound to the PDU to be sent, or 0 for Idle cells*  cellCount : number of cells to send (data cell or idle cell)*  cellType : Type of the cells to send (data cells or idle cells)*/PRIVATE voidixAtmdAccCellTx (UINT32 **qMgrEntryPtr,                 unsigned int physicalAddress,                 unsigned int cellCount,                 unsigned int cellType){    IX_ATMDACC_ENSURE (cellCount != 0, "Bad cell count!");    /* The following algorthim is designed for performance and    * is a variation on Duff's Device, which is widely documented.    * - ``Duff's device'' had come up in comp.lang.c as soon as 1983    * - The device is to express general loop unrolling directly in C.      * - The device is legal dpANS C.  X3J11 considered it carefully and decided that it     *   was legal. The device is also legal C++, since Bjarne uses it in his book.     *    * The algorithm is designed to replace the following slow code    *    * while (cellCount > 15)    * {  qEntry = buildEntry(15 cells, physicaladdress, type);    *    qMgrWriteReturnStatus = qMgrWrite(...qEntry)    *    cellCount -= 15;    * }    * if (cellCount > 0)    * {  qEntry = buildEntry(cellCount, physicaladdress, type);    *    qMgrWriteReturnStatus = qMgrWrite(...qEntry)    * }    * return qMgrWriteReturnStatus    *    * The algorithm exploits    * the fall through of the switch statement to process    * successive queue entries of NPE_TX_MAXCELLS_PER_QENTRY cells,    * Any residual cells are placed in the final queue entryin a separate step    * after the loop ends.    * This reduces the number of a control loop iterations by a factor of 8.    */    if(cellCount > NPE_TX_MAXCELLS_PER_QENTRY)    {        /* get the number of qEntries with a full count of cells        * using an integer division with round-down to the previous integer         */        unsigned int qEntryCount = cellCount / NPE_TX_MAXCELLS_PER_QENTRY;        /* get the number of iterations using an integer division         * with round-up to the next integer         */        unsigned int n = (qEntryCount + 7)/8;        /* build one entry with the maximum of cells per entry . This queue         * entry is always        */        UINT32 qEntry = ixAtmdAccTxQueueEntryBuild (physicalAddress,            NPE_TX_MAXCELLS_PER_QENTRY,            cellType);               /* store X queue entries with a number of cells        * equal to NPE_TX_MAXCELLS_PER_QENTRY        */        switch(qEntryCount & 7)        {        case 0: do {  *(*qMgrEntryPtr)++ = qEntry;        case 7:       *(*qMgrEntryPtr)++ = qEntry;        case 6:       *(*qMgrEntryPtr)++ = qEntry;        case 5:       *(*qMgrEntryPtr)++ = qEntry;        case 4:       *(*qMgrEntryPtr)++ = qEntry;        case 3:       *(*qMgrEntryPtr)++ = qEntry;        case 2:       *(*qMgrEntryPtr)++ = qEntry;        case 1:       *(*qMgrEntryPtr)++ = qEntry;                } while (--n > 0);        }        /* check for any more cells to process (sub and mul are faster than mod)        * cellCount  = qEntryCount % NPE_TX_MAXCELLS_PER_QENTRY        */        cellCount -= qEntryCount * NPE_TX_MAXCELLS_PER_QENTRY;        if(cellCount == 0)        {            /* all done (the number of cells was an            * exact multiple of NPE_TX_MAXCELLS_PER_QENTRY            */            return;        }    }     /* store 1 queue entry with a number of cells    * between 1 and NPE_TX_MAXCELLS_PER_QENTRY (included)    */    *(*qMgrEntryPtr)++ = ixAtmdAccTxQueueEntryBuild (physicalAddress,        cellCount,         cellType);    return;}/*--------------------------------------------------------* Transmit cells over this channel*/PRIVATE voidixAtmdAccChannelTx (UINT32 **qMgrEntryPtr,                    IxAtmdAccTxVcDescriptor * vcDescriptor,                    unsigned int cellCount){    IX_ATMDACC_TX_QUEUE *txSwQueue = &vcDescriptor->queue;    /* process the number of cells for this channel */    while (cellCount != 0)

⌨️ 快捷键说明

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