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

📄 ixatmsch.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 2 页
字号:
	}											\    }                                                                                           \}PRIVATE IX_STATUSixAtmSchValidRtVcSearch(IxAtmLogicalPort port, 			IxAtmServiceCategory atmService, 			IxAtmSchedulerVcId* schRtQueueHead){    IxAtmSchedulerVcId thisRtVc = IX_ATMSCH_NULL_INDEX;    IxAtmSchedulerVcId tmpRtVc = IX_ATMSCH_NULL_INDEX;    thisRtVc = *schRtQueueHead;    /* If there is no rt queue && count is zero */    if ((thisRtVc == IX_ATMSCH_NULL_INDEX) ||	(ixAtmSchVcTable[thisRtVc].count == 0))    {	return IX_SUCCESS;    }    if (ixAtmSchVcTable[thisRtVc].atmService != atmService)    { 	while (((tmpRtVc = ixAtmSchVcTable[thisRtVc].nextVc) != IX_ATMSCH_NULL_INDEX) &&	       !(ixAtmSchVcTable[tmpRtVc].schInfo.cet & IX_ATMSCH_UINT_MASK))    	{	    if ((ixAtmSchVcTable[tmpRtVc].atmService == atmService) &&	        (ixAtmSchVcTable[tmpRtVc].schInfo.cet <= ixAtmSchTime[port]) &&	        (ixAtmSchVcTable[tmpRtVc].count != 0))	    {	        /* found that VC. Swap it to the head of the list */	   	ixAtmSchVcTable[thisRtVc].nextVc = ixAtmSchVcTable[tmpRtVc].nextVc;		ixAtmSchVcTable[tmpRtVc].nextVc = *schRtQueueHead;		*schRtQueueHead = tmpRtVc;		ixAtmSchRtQueueHead[port] = tmpRtVc;	    	return IX_SUCCESS;	    }	    /* continue to search for the next VC of same ATM service category */	    thisRtVc = ixAtmSchVcTable[thisRtVc].nextVc;	}	/* End of the queue is reached, i.e. no VC found in the list 	 * or CET is not complied or count is zero. So return FALSE */	return IX_FAIL;    } /* if the rt queue list is actived, search for correct atmService */    return IX_SUCCESS;}IX_STATUSixAtmSchTableUpdate(IxAtmLogicalPort port,                     unsigned int maxCells,                    IxAtmScheduleTable **retTable){    int entryCnt; /* a counter to create the sch table */    UINT32 numUbrToSend; /* number of cells (UBR or idle) that can be sched */    UINT32 cellCount = 0; /* counter for the number of cell sched */    IxAtmSchPortSchedulingInfo *portSchInfo; /* contains info for that port */    UINT32 timePerCell; /* the time for each cell */    IxAtmScheduleTable *schTable; /* contains scheduling table info */        /* These variables are used for UBR list */    IxAtmSchedulerVcId prevUBR = IX_ATMSCH_NULL_INDEX;    IxAtmSchedulerVcId schNextUbrToBeScheduled;    /* thisSchInfo is used to hold the information of the real-time VC    * scheduling information */    IxAtmSchVcSchedInfo *thisSchInfo;    /* These variables are used for real-time list */    IxAtmSchedulerVcId schRtQueueHead;    IxAtmSchedulerVcId prevRtVc;    IxAtmSchedulerVcId thisRtVc;    IxAtmSchedulerVcId tmpRtVc;    /* Update the count for calls to this function */    IX_ATMSCH_STATS(ixAtmSchStats[port].scheduleTableCalls ++;);    if ((port>=IX_UTOPIA_PORT_0) &&         (port< IX_UTOPIA_MAX_PORTS)&&        (ixAtmSchedulingEnabled[port]))    {        portSchInfo = &portSchedulingInfo[port];        /* make a local copy. The time per cell and current 	 * scheduler time for that particular port */         timePerCell    = portSchInfo->timePerCell;        schNextUbrToBeScheduled = ixAtmSchNextUbrToBeScheduled[port];       	schRtQueueHead = ixAtmSchRtQueueHead[port];	/* Point to the scheduler table for this port */        schTable            = &portSchInfo->schTable;	schTable->tableSize = 0;                   	for (entryCnt=0;(entryCnt < IX_ATMSCH_MAX_TABLE_ENTRIES )&&(cellCount < maxCells); entryCnt++) 	{	    RESORT_RT_QUEUE_PRIORITY(port, schRtQueueHead);	    if ((ixAtmSchTime[port] & (IX_ATMSCH_UINT_MASK >> 1)) ||		((schRtQueueHead != IX_ATMSCH_NULL_INDEX) && 		 (ixAtmSchVcTable[schRtQueueHead].schInfo.cet & (IX_ATMSCH_UINT_MASK >> 1))))	    {		/* This should happen rarely so it is		 * acceptable to perform a function call as it is so		 * infrequent */		ixAtmSchTimerOverrun(port);	    }	    /* Process for real time VC */	    while ((schRtQueueHead != IX_ATMSCH_NULL_INDEX) &&		   (ixAtmSchTime[port] >= ixAtmSchVcTable[schRtQueueHead].schInfo.cet) &&		   (entryCnt < IX_ATMSCH_MAX_TABLE_ENTRIES))	    {		/* first schedule one real-time cell if there any */		/* make a local copy of the scheduling information of the VC */		thisSchInfo = &ixAtmSchVcTable[schRtQueueHead].schInfo;		if (ixAtmSchVcTable[schRtQueueHead].count > 0)		{		    /* Send one real-time cell. Decrement the cell count &		     * increment the table entry count*/		    SEND_CELLS(1,			       ixAtmSchVcTable[schRtQueueHead].connId, 			       entryCnt);		    ixAtmSchVcTable[schRtQueueHead].count--;		    entryCnt++;		    /* calculate the next tx time for this VC */		    if ((ixAtmSchVcTable[schRtQueueHead].atmService == IX_ATM_RTVBR) ||			(ixAtmSchVcTable[schRtQueueHead].atmService == IX_ATM_VBR))		    {			/* This is for VBR - based on PCR, SCR and BT value */			thisSchInfo->cetPcr += thisSchInfo->usPcr;			thisSchInfo->cetScr += thisSchInfo->usScr;			thisSchInfo->cet = MAX(thisSchInfo->cetPcr,					       thisSchInfo->cetScr - thisSchInfo->bt);			if (ixAtmSchVcTable[schRtQueueHead].vbrPcrCellsCnt > 0)			{			    ixAtmSchVcTable[schRtQueueHead].vbrPcrCellsCnt--;			}			else			{			    if (ixAtmSchVcTable[schRtQueueHead].vbrScrCellsCnt == 0)			    {				ixAtmSchTimerOverrun(port);			    }			    if (ixAtmSchVcTable[schRtQueueHead].vbrScrCellsCnt ==				(ixAtmSchVcTable[schRtQueueHead].schInfo.scr * 				 IX_ATMSCH_SCR_PERIOD_IN_SEC))			    {				/* Restore MBS value. Burst Tolerance will be calc by				 * TimerOverrun */				ixAtmSchVcTable[schRtQueueHead].vbrPcrCellsCnt = 				    ixAtmSchVcTable[schRtQueueHead].schInfo.mbs;								/* Reset SCR cell count */				ixAtmSchVcTable[schRtQueueHead].vbrScrCellsCnt = 0;								ixAtmSchTimerOverrun(port);			    }			    else			    {				ixAtmSchVcTable[schRtQueueHead].vbrScrCellsCnt++;			    }			}		    }		    else 		    {			/* This is for CBR - based on PCR value only */			thisSchInfo->cetPcr += thisSchInfo->usPcr;			thisSchInfo->cet = thisSchInfo->cetPcr;		    }		    if (ixAtmSchVcTable[schRtQueueHead].count == 0)		    {			/* There are no more cells to be scheduled. Hence set the 			 * cet's MSB with the MASK value. It will be placed at VC (now idle)			 * at the back of the queue */			ixAtmSchVcTable[schRtQueueHead].schInfo.cet |= IX_ATMSCH_UINT_MASK;		    }		}		else 		{		    /* There are no cells to be scheduled. The VC becomes idle by		     * setting the most significant bit */		    ixAtmSchVcTable[schRtQueueHead].schInfo.cet|= IX_ATMSCH_UINT_MASK;		}		RESORT_RT_QUEUE_HEAD();		RESORT_RT_QUEUE_PRIORITY(port,schRtQueueHead);	    } /* while*/	    /* Leading UBR cells in this table, recalculate the	     * number of UBR cells to send based on the current	     * schTime. */	    if (schRtQueueHead != IX_ATMSCH_NULL_INDEX)	    {		if ((cellCount >= portSchInfo->minCellsToSchedule) &&		    (ixAtmSchVcTable[schRtQueueHead].count == 0))		{		    /* the cell counter exceeds the min table size and there are no		     * cells to be schedule */		    break;		}		else if (ixAtmSchVcTable[schRtQueueHead].schInfo.cet & (IX_ATMSCH_UINT_MASK))		{		    if (cellCount < portSchInfo->minCellsToSchedule)		    {			numUbrToSend = MAX(((INT32)portSchInfo->minCellsToSchedule - (INT32)cellCount), 1);		    }		    else		    {			break; /* for (entryCnt ...) */		    }		}		else 		{		   		    numUbrToSend = ((ixAtmSchVcTable[schRtQueueHead].schInfo.cet - 				     ixAtmSchTime[port]) / timePerCell) + 1;		}	    }	    else 	    {		/* No real-time VC registered */		if (cellCount < portSchInfo->minCellsToSchedule)		{		    numUbrToSend = MAX(((INT32)portSchInfo->minCellsToSchedule - (INT32)cellCount), 1);		}		else		{		    break; /* for (entryCnt...) */		}	    }	    /* Modify the number of UBR so the maxCells is not exceeded.	     * The maxCells and cellCount are cast with INT32 so that the 	     * negative value can be compared. Now the schTable is expecting	     * an entry (after completing the above's algorithm). Hence the 	     * numUbrToSend must have at least 1. Zero is not valid as it may 	     * cause the system failure (i.e. no such thing as sending zero cell) */            if ( (numUbrToSend+cellCount) > maxCells )            {                numUbrToSend = MAX( ((INT32) maxCells - (INT32) cellCount),1);            }	    /* Now fill the gap between real-time cells with cells from the	     * UBR VCs. */	    while ((numUbrToSend > 0) && (entryCnt < IX_ATMSCH_MAX_TABLE_ENTRIES))	    {		if ( (schNextUbrToBeScheduled != IX_ATMSCH_NULL_INDEX) &&		     (ixAtmSchVcTable[schNextUbrToBeScheduled].count >= numUbrToSend) )		{                  /* CASE 1 - enough UBR in this VC to fulfill numUbrToSend */                    IX_OSAL_ENSURE( (ixAtmSchVcTable[schNextUbrToBeScheduled].port == port),                                "IxAtmSch Major internal error") ;		                        SEND_CELLS (numUbrToSend,                                 ixAtmSchVcTable[schNextUbrToBeScheduled].connId,                                 entryCnt);		    ixAtmSchVcTable[schNextUbrToBeScheduled].count -= numUbrToSend;		    numUbrToSend = 0;		}		else if ( (schNextUbrToBeScheduled != IX_ATMSCH_NULL_INDEX) &&			  (ixAtmSchVcTable[schNextUbrToBeScheduled].count > 0) )		{		    /* CASE 2 - some, but not enough UBR in this VC to fulfill numUbrToSend */                    IX_OSAL_ENSURE((ixAtmSchVcTable[schNextUbrToBeScheduled].port == port),                               "IxAtmSch Major internal error") ;		                        SEND_CELLS(ixAtmSchVcTable[schNextUbrToBeScheduled].count,                                ixAtmSchVcTable[schNextUbrToBeScheduled].connId, 			       entryCnt);		    numUbrToSend -= ixAtmSchVcTable[schNextUbrToBeScheduled].count;		    ixAtmSchVcTable[schNextUbrToBeScheduled].count = 0;                    		    entryCnt++;		}		else if ( (schNextUbrToBeScheduled == IX_ATMSCH_NULL_INDEX) ||			  (prevUBR == schNextUbrToBeScheduled) )		{		    /* CASE 3 - There is no UBR enabled or we                      * have gone all the way around the UBR		     * chain and there is no data in it. If we		     * have real-time cells or we have sent UBR this		     * time we insert required idle		     * cells. Otherwise the table is empty.		     */		    if (((schRtQueueHead != IX_ATMSCH_NULL_INDEX) && 			 (ixAtmSchVcTable[schRtQueueHead].count > 0)) ||			(cellCount > 0) )		    {			SEND_CELLS(numUbrToSend,                                    IX_ATM_IDLE_CELLS_CONNID,                                    entryCnt);			IX_ATMSCH_STATS(ixAtmSchStats[port].idleCellsScheduled += numUbrToSend;);			numUbrToSend = 0;		    }		    else		    {			*retTable = NULL;                        ixAtmSchNextUbrToBeScheduled[port] = schNextUbrToBeScheduled;			                        return IX_ATMSCH_RET_QUEUE_EMPTY;		    }		}		/* Find the next UBR VC with cells, stop if we		 * have gone all the way around the UBR chain.		 */		if (prevUBR != schNextUbrToBeScheduled)		{		    prevUBR = schNextUbrToBeScheduled;		    do		    {			schNextUbrToBeScheduled 			    = ixAtmSchVcTable[schNextUbrToBeScheduled].nextVc;		    }		    while ( (prevUBR != schNextUbrToBeScheduled) &&			    (ixAtmSchVcTable[schNextUbrToBeScheduled].count == 0) );		}	    } /* while ((numUbrToSend > 0) ... */	} /* for */        ixAtmSchNextUbrToBeScheduled[port] = schNextUbrToBeScheduled;	schTable->totalCellSlots    = cellCount;	IX_ATMSCH_STATS(ixAtmSchStats[port].cellsScheduled    += cellCount;);	schTable->table             = portSchInfo->schTableEntries;	*retTable = schTable;	return IX_SUCCESS;    }    return IX_FAIL;}/************************************************************************/

⌨️ 快捷键说明

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