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

📄 ixatmsch.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * @file        IxAtmSch.c * @author Intel Corporation * @date        29-JUL-2000 * * @brief Implementiation file for the example Atm scheduler. *  * Design Notes: *    14-SEP-00  A different implementation of the UBR chaining *               which keeps only those UBR VCs which have pending *               cells on the chain is available in CVS version 1.16. *    18-DEC-00  Added a 'sch' prefix to all global variables.  The  *               coding standards specify that this prefix should be *               IxAtmSch, but due to the complexity of these  *               functions, names are being maintained as short as *               possible to retain readability. *    02-JAN-01  This file is compiled automatically into the BSP *               by the ixp22x BSP Makefile.  It is  *               not, therefore, built by a standard arm_sw build. * *    26-FEB-02  Ported this code from IXP22X. Expanded to support *               multiple ports. Adjusted API to accommodate new  *               IxAtmdAcc component. *  *  * @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 -- */#include "IxOsal.h"#include "IxAtmSch.h"#include "IxAtmSch_p.h"#include "IxAtmSchUtils_p.h"/* * #defines and macros used in this file. */#define IX_ATMSCH_QUEUE_LIMIT 100000#define MAX(a, b) ((a > b)?a:b)#define MIN(a, b) ((a < b)?a:b)typedef struct {    UINT32 timePerCell;         /* Time per cell in us */    UINT32 minCellsToSchedule;  /* minimum number of cells to schedule */    UINT32 currentSchTime;    IxAtmScheduleTable schTable;/* A pointer to the schedule table for this port */    IxAtmScheduleTableEntry schTableEntries[IX_ATMSCH_MAX_TABLE_ENTRIES]; /* The Sched table */}IxAtmSchPortSchedulingInfo;/* * Variable declarations global to this file only. Externs are followed by * static variables.  *//* Holds the per port scheduling state information */static IxAtmSchPortSchedulingInfo portSchedulingInfo[IX_UTOPIA_MAX_PORTS];/*  * Variable declarations used by other source files in this component  */BOOL               ixAtmSchedulingEnabled[IX_UTOPIA_MAX_PORTS];IxAtmSchedulerVcId ixAtmSchNextUbrToBeScheduled[IX_UTOPIA_MAX_PORTS];IxAtmSchedulerVcId ixAtmSchRtQueueHead[IX_UTOPIA_MAX_PORTS];IxAtmSchVcInfo     ixAtmSchVcTable[IX_ATM_MAX_NUM_AAL_OAM_TX_VCS]; IxAtmSchStats      ixAtmSchStats[IX_UTOPIA_MAX_PORTS]; UINT32             ixAtmSchBaseTime[IX_UTOPIA_MAX_PORTS];UINT32             ixAtmSchTime[IX_UTOPIA_MAX_PORTS];UINT32             ixAtmSchCacPortAllocated[IX_UTOPIA_MAX_PORTS];PRIVATE IX_STATUSixAtmSchValidRtVcSearch(IxAtmLogicalPort port, 			IxAtmServiceCategory atmService, 			IxAtmSchedulerVcId* schRtQueueHead);/************************************************************************/voidixAtmSchedulingInit(void){    IxAtmLogicalPort i;    /* Initialise the scheduling info for all ports */    memset(portSchedulingInfo, 0, sizeof(portSchedulingInfo));    for (i=0; i<IX_UTOPIA_MAX_PORTS; i++)     {        ixAtmSchNextUbrToBeScheduled[i] = IX_ATMSCH_NULL_INDEX;	ixAtmSchRtQueueHead[i]          = IX_ATMSCH_NULL_INDEX;        ixAtmSchedulingEnabled[i]       = FALSE;	ixAtmSchBaseTime[i]             = 0;	ixAtmSchTime[i]                 = 0;	ixAtmSchCacPortAllocated[i]     = 0;    }    for (i=0; i<IX_ATM_MAX_NUM_AAL_OAM_TX_VCS; i++)    {        ixAtmSchVcTable[i].inUse = FALSE;        ixAtmSchVcTable[i].port  = IX_UTOPIA_MAX_PORTS;    }}/************************************************************************/voidixAtmSchCellTimeSet(IxAtmLogicalPort port, UINT32 cellTime){    portSchedulingInfo[port].timePerCell = cellTime;}/************************************************************************/UINT32ixAtmSchCellTimeGet(IxAtmLogicalPort port){    return portSchedulingInfo[port].timePerCell;}/************************************************************************/voidixAtmSchMinCellsSet(IxAtmLogicalPort port, UINT32 minCellsToSchedule){    portSchedulingInfo[port].minCellsToSchedule = minCellsToSchedule;}/************************************************************************/UINT32ixAtmSchMinCellsGet(IxAtmLogicalPort port){    return portSchedulingInfo[port].minCellsToSchedule;}/************************************************************************/PUBLIC IX_STATUS ixAtmSchVcQueueUpdate( IxAtmLogicalPort port,                        IxAtmSchedulerVcId vcId,                        unsigned int numberOfCells){    IxAtmSchedulerVcId thisRtVc = IX_ATMSCH_NULL_INDEX;    /*      *     * Putting the most common scenario in as the successful     * branch of the if statement saves another 10%.       */    if ((vcId < IX_ATM_MAX_NUM_AAL_OAM_TX_VCS) &&	(vcId >= 0) &&	(ixAtmSchVcTable[vcId].inUse == TRUE)&&	(ixAtmSchVcTable[vcId].port  == port))    {	/* This is hard to read but is a slightly faster than doing a	   seperate increment and test */	if ((ixAtmSchVcTable[vcId].count += numberOfCells) < IX_ATMSCH_QUEUE_LIMIT)	{	    IX_ATMSCH_STATS(ixAtmSchStats[port].updateCalls++;);	    IX_ATMSCH_STATS(ixAtmSchStats[port].cellsQueued += numberOfCells;);	    	    /* Performing queue update for real-time VC */	    if (ixAtmSchVcTable[vcId].schInfo.cet & IX_ATMSCH_UINT_MASK)	    {		/* Real time list exist. Perform queue update here. No need to check		   whether the list is NULL*/				if (ixAtmSchRtQueueHead[port] != vcId)		{		    /* The interested VC is not at the head of the queue */		    thisRtVc = ixAtmSchRtQueueHead[port];		    		    while (thisRtVc != IX_ATMSCH_NULL_INDEX)		    {			/* The loop searches for the correct VC */			      			if (ixAtmSchVcTable[thisRtVc].nextVc == vcId)			{			    /* Found the VC that the current one is pointing to 			     * The interested VC's that it is pointing to is stored into			     * the current's nextVc */			    ixAtmSchVcTable[thisRtVc].nextVc = ixAtmSchVcTable[vcId].nextVc;							    /* break from the while loop */			    break;			}			/* If not found,gGet the next VC in the list */			thisRtVc = ixAtmSchVcTable[thisRtVc].nextVc;		    } /* while */					    /* The interested VC is brought forward to the head of the queue 		     * and its nextVc is now pointing to the old queue head */		    ixAtmSchVcTable[vcId].nextVc = ixAtmSchRtQueueHead[port];		}				/* Do this here so the queue remains sorted at all times */		ixAtmSchVcTable[vcId].schInfo.cetScr     = 		    ixAtmSchVcTable[vcId].schInfo.cetPcr     = 		    ixAtmSchVcTable[vcId].schInfo.cet        = 		    MAX(ixAtmSchTime[port], (ixAtmSchVcTable[vcId].schInfo.cet ^ IX_ATMSCH_UINT_MASK));				/* Now the interested VC is the head of the queue */		ixAtmSchRtQueueHead[port] = vcId;	    } /* End if statement for real time*/	    	    return IX_SUCCESS;	}	else	{	    /* doing this is faster than a test and increment on every	       call, we will rarely go inside this  */	    ixAtmSchVcTable[vcId].count -= numberOfCells;	    IX_ATMSCH_STATS(ixAtmSchStats[port].queueFull ++;);	    return IX_ATMSCH_RET_QUEUE_FULL;	}    }    return IX_FAIL;}/************************************************************************/PUBLIC IX_STATUSixAtmSchVcQueueClear( IxAtmLogicalPort port,                       IxAtmSchedulerVcId vcId){    if ((vcId < IX_ATM_MAX_NUM_AAL_OAM_TX_VCS) &&	(vcId >= 0) &&        (ixAtmSchVcTable[vcId].inUse == TRUE)&&	(ixAtmSchVcTable[vcId].port  == port))    {	ixAtmSchVcTable[vcId].count = 0;	if (ixAtmSchVcTable[vcId].schInfo.cetPcr != 0)	{	    /* i.e. this is a RT VC */	    ixAtmSchVcTable[vcId].schInfo.cet |= IX_ATMSCH_UINT_MASK;	    /* This is to sort the real-time list */	    ixAtmSchBubbleSortRtVcQueue(port);	}	return IX_SUCCESS;    }    return IX_FAIL;}/************************************************************************//* This function is big because we do not have the performance budget * to make sub functions out of it.  * * This is called when the client decides it needs a new sequence of * cells to send (probably because the transmit queue is near to * empty for this ATM port) * * This function cannot be interrupted by a call to ubrVcChainRemove  * since such a call could cause errors through a non-atomic modification  * of the ixAtmSchNextUbrToBeScheduled variable. * * SchTime in this function is maintained in microseconds and is updated * by the SEND_CELLS macro every time cells are sent. * * The algorithm will schedule at least the lesser of minCellsToSchedule * cells and maxCells. The value of minCellsToSchedule should be a trade-off * between maximum VBR cell delay (low value) and efficient execution of the sch  * table (high value). Tuning of this value is expected to be performed on a * per-application basis. *//* This "inline" function is only used in the following ixAtmSchTableUpdate() */#define SEND_CELLS(COUNT, CONNID, TBL_INDEX)                           \{					                               \    portSchInfo->schTableEntries[(TBL_INDEX)].connId        = (CONNID);\    portSchInfo->schTableEntries[(TBL_INDEX)].numberOfCells = (COUNT); \    ixAtmSchTime[port] += (timePerCell * (COUNT));                     \    schTable->tableSize = (TBL_INDEX)+1;                               \    cellCount += (COUNT);		                               \}/* Parameters are simply index vars used to reference the table */#define RESORT_RT_QUEUE_HEAD()                         		\{								\    prevRtVc = schRtQueueHead;			                \    thisRtVc = ixAtmSchVcTable[schRtQueueHead].nextVc;		\    while( (thisRtVc != IX_ATMSCH_NULL_INDEX) &&	        \	   ( ixAtmSchVcTable[thisRtVc].schInfo.cet <=           \	     ixAtmSchVcTable[schRtQueueHead].schInfo.cet) )     \    {		                                                \	prevRtVc = thisRtVc;					\	thisRtVc = ixAtmSchVcTable[thisRtVc].nextVc;		\    }								\    								\    /* Move the head of the queue into the new position */      \    if (prevRtVc != schRtQueueHead) /* i.e. >1 RT VC */		\    {								\	ixAtmSchVcTable[prevRtVc].nextVc = schRtQueueHead;	\	tmpRtVc = ixAtmSchVcTable[schRtQueueHead].nextVc;       \	ixAtmSchVcTable[schRtQueueHead].nextVc = thisRtVc;      \	schRtQueueHead = tmpRtVc;				\        ixAtmSchRtQueueHead[port] = schRtQueueHead;             \    }	                                                        \}#define RESORT_RT_QUEUE_PRIORITY(PORT, schRtQueueHead)                          	\{                                                               		                \    if (ixAtmSchValidRtVcSearch(PORT, IX_ATM_CBR, &schRtQueueHead) != IX_SUCCESS) {		\	if (ixAtmSchValidRtVcSearch(PORT,IX_ATM_RTVBR, &schRtQueueHead) != IX_SUCCESS) { 	\	    if(ixAtmSchValidRtVcSearch(PORT, IX_ATM_VBR, &schRtQueueHead) != IX_SUCCESS) {	\	    }											\

⌨️ 快捷键说明

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