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

📄 ixatmmdatapath.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 2 页
字号:
/**  * @file    IxAtmmDataPath.c * @author Intel Corporation * @date    1-MAR-2002 * * @brief   IxAtmm data path sub component (AtmmDataPath) APIs. *          No rollback in initialization if any part of initialization fails. *          Assumptions: *           - DemandUpdate callback from IxAtmd is serialized per VC. *           - TxLow callback from IxAtmd will occur in an IRQ context *           - VcDemandUpdate callback from IxAtmd can occur in IRQ or task context *               => TxLow callback can interrupt VcDemandUpdate callback *               => TxLow callback cannot interrupt VcDemandUpdate callback *           - No OS calls made in IxAtmmPortTxProcess, i.e. safe to intLock *            *  * @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 system defined include files required *//* * Put the user defined include files required */#include "IxOsal.h"#include "IxAtmTypes.h"#include "IxAtmm.h"#include "IxAtmdAccCtrl.h"#include "IxAtmSch.h"#include "IxAtmmDataPath_p.h"/* * #defines and macros used in this file. *//* * Process Tx Done queue every 1/2 second to ensure queue gets cleared out * when idle/low traffic. */#define IX_ATMM_TX_DONE_PERIOD_MSECS        500/* * Process Rx low priority queue every 20 msecs */#define IX_ATMM_RX_LO_PRIORITY_PERIOD_MSECS 20/* * Tx Vc Q fast mutexes, one Q per port. */#define IX_ATMM_TX_MUTEX_TRY_LOCK(port) ixOsalFastMutexTryLock (&ixAtmmTxBusyFastMutex[(port)])#define IX_ATMM_TX_MUTEX_UNLOCK(port)   (void)ixOsalFastMutexUnlock (&ixAtmmTxBusyFastMutex[(port)])/* * Port State fast mutexes, one per port. */#define IX_ATMM_PORT_MUTEX_TRY_LOCK(port) ixOsalFastMutexTryLock (&ixAtmmPortFastMutex[(port)])#define IX_ATMM_PORT_MUTEX_UNLOCK(port)   (void)ixOsalFastMutexUnlock (&ixAtmmPortFastMutex[(port)])/* *  Tx timer based *//* * Typedefs whose scope is limited to this file. */typedef struct {    IxOsalThread rxLoPriorityId;    IxOsalThread txDoneId;} IxAtmmTaskIds;/* * Variable declarations global to this file only. Externs are followed by * static variables. */static IxAtmmTaskIds ixAtmmTaskIds;/* * VC query callback registered by IxAtmm.c */static IxAtmmVcQueryCallback vcQueryCallback = NULL;/* * Fast muxtexs, initialized later */static IxOsalFastMutex ixAtmmTxBusyFastMutex[IX_UTOPIA_MAX_PORTS];static IxOsalFastMutex ixAtmmPortFastMutex[IX_UTOPIA_MAX_PORTS];/* * TX Vc Q size, needed when system goes IDLE -> BUSY */static unsigned ixAtmmTxQSize[IX_UTOPIA_MAX_PORTS];/* * Variables are moved here since they are required while doing un-init * Scheduling Init done array used by ixAtmmTxSchedulingInitDone and txSchedulingUninit */static BOOL ixAtmmTxSchedulingInitDone[IX_UTOPIA_MAX_PORTS];/* Flag used by ixAtmmTxDoneInit and ixAtmmTxDoneUninit */static BOOL ixAtmmTxDoneInitDone       = FALSE;/* Flags used by Rx Init and Rx Uninit */static BOOL ixAtmmRxHiPriorityInitDone = FALSE;static BOOL ixAtmmRxLoPriorityInitDone = FALSE;/* * Static function prototypes */PRIVATE IX_STATUSixAtmmTxDoneInit (void);PRIVATE IX_STATUSixAtmmTxSchedulingInit (IxAtmLogicalPort port);PRIVATE IX_STATUSixAtmmRxHiPriorityInit (void);PRIVATE IX_STATUSixAtmmRxLoPriorityInit (void);PRIVATE voidixAtmmTxLowHandle (IxAtmLogicalPort port, unsigned numRemainingCells);PRIVATE IX_STATUSixAtmmTxDoneHandle (unsigned numOfPdusToProcess,		    unsigned *reservedPtr);PRIVATE IX_STATUSixAtmmVcDemandUpdate (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, unsigned numberOfCells);PRIVATE voidixAtmmVcQueueClear (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId);PRIVATE IX_STATUS ixAtmmVcIdGet (IxAtmLogicalPort port,	       unsigned vpi,	       unsigned vci,	       IxAtmConnId connId,	       IxAtmSchedulerVcId *vcId);PRIVATE IX_STATUSixAtmmTxDoneLoop (void* arg, void** retArgObj);PRIVATE IX_STATUSixAtmmRxLoPriorityLoop (void* arg,                        void** ptrRetObj);PRIVATE IX_STATUSixAtmmTxSchedulingUninit (IxAtmLogicalPort port);PRIVATE IX_STATUSixAtmmTxDoneUninit (void);PRIVATE IX_STATUSixAtmmRxHiPriorityUninit (void);PRIVATE IX_STATUSixAtmmRxLoPriorityUninit (void);/* * Function definitons */voidixAtmmVcQueryCallbackRegister ( IxAtmmVcQueryCallback callback){    /* NULL callback not supported */    IX_OSAL_ASSERT(callback != NULL);    vcQueryCallback = callback;}voidixAtmmVcQueryCallbackUnregister(void){    /* Reset the vcQueryCallback */    vcQueryCallback = NULL;}PRIVATE IX_STATUSixAtmmTxDoneLoop (void* arg, void** retArgObj){    unsigned dummyPtr;    IX_STATUS retval;    while (ixAtmmTxDoneInitDone)     {	/* 	 * Sleep for the timer duration 	 */	ixOsalSleep (IX_ATMM_TX_DONE_PERIOD_MSECS);	/* 	 * Service Tx Done, process all the queue         * but release the fast mutex to allow interrupts         * running and service tx done when it is really needed. 	 */	retval = ixAtmmTxDoneHandle (IX_ATMDACC_ALLPDUS, &dummyPtr);		IX_OSAL_ENSURE(retval == IX_SUCCESS, "Call to ixAtmmTxDoneHandle() failed");    }		    ixOsalSleep (50);    return IX_SUCCESS;}PRIVATE IX_STATUSixAtmmRxLoPriorityLoop (void* arg,                        void** ptrRetObj){    unsigned dummyPtr;    IX_STATUS retval;    while (ixAtmmRxLoPriorityInitDone)    {	/* 	 * Sleep for the timer duration 	 */	ixOsalSleep (IX_ATMM_RX_LO_PRIORITY_PERIOD_MSECS);		/*	 * Service Rx low priority queue, process all in Q	 */	retval = ixAtmdAccRxDispatch ( IX_ATM_RX_B,					     IX_ATMDACC_ALLPDUS,					     &dummyPtr);	IX_OSAL_ENSURE(retval == IX_SUCCESS, "Call to ixAtmdAccRxDispatch() failed");    }	    ixOsalSleep (50);    return IX_SUCCESS;	}PUBLIC IX_STATUSixAtmmPortEnable (IxAtmLogicalPort port){   unsigned int maxTxCells;   UINT32 lockKey;   IX_STATUS retval;   retval = ixAtmdAccPortEnable(port);   if (retval == IX_SUCCESS)   {       /* ensure no interrupt is running */       lockKey = ixOsalIrqLock();          retval = ixAtmdAccPortTxFreeEntriesQuery(port, &maxTxCells);          if(retval == IX_SUCCESS)       {	   IX_ATMM_PORT_MUTEX_UNLOCK(port);	   if (maxTxCells == ixAtmmTxQSize[port])	   {	       /* there are no entries in the TX queue, it is necessary		  to restart the transmission of cells 	       */	       ixAtmmTxLowHandle (port, maxTxCells);	   }	   else	   {	       /* there are cells in the tx queue : the NPE will consume 		  them and this will trigger a tx Low interrupt. 		  The TX traffic will start again	       */	   }       }       ixOsalIrqUnlock(lockKey);   }   else if (retval == IX_ATMDACC_WARNING)   {       /* the port is already up */       retval = IX_SUCCESS;   }   else   {       retval = IX_FAIL;   }   return retval;}PUBLIC IX_STATUSixAtmmPortDisable (IxAtmLogicalPort port){    IX_STATUS retval;    UINT32 lockKey;        /* ensure no interrupt is running        (scheduling and transmission is done under interrupts)     */    lockKey = ixOsalIrqLock();        IX_ATMM_PORT_MUTEX_TRY_LOCK(port);        /* now, cell transmission is stopped */    ixOsalIrqUnlock(lockKey);    /* tell the NPE to stop draining the TX queue */    retval = ixAtmdAccPortDisable(port);    if (retval == IX_SUCCESS)    {	/* wait until a Disable is complete */	while (ixAtmdAccPortDisableComplete(port) == FALSE)	{	    /* since TX done is processing the response, the time 	       to wait is linked to the TxDone polling time */	    ixOsalSleep(IX_ATMM_TX_DONE_PERIOD_MSECS/2 );	}    }    else if (retval == IX_ATMDACC_WARNING)    {	/* the port is already down */        retval = IX_SUCCESS;    }    else    {        retval = IX_FAIL;    }    IX_ATMM_PORT_MUTEX_UNLOCK(port);    return retval;}IX_STATUSixAtmmDataPathSetup (IxAtmLogicalPort port){    IX_STATUS retval = IX_SUCCESS;    /*     * Initialize Tx Scheduling control     */    retval = ixAtmmTxSchedulingInit (port);    if (retval == IX_SUCCESS)    {	/*	 * Initialize Tx Done control	 */	retval = ixAtmmTxDoneInit ();    }        if (retval == IX_SUCCESS)    {	/*	 * Initialize Rx High Priority control	 */	retval = ixAtmmRxHiPriorityInit ();    }    if (retval == IX_SUCCESS)    {	/*	 * Initialize Rx Low Priority control	 */	retval = ixAtmmRxLoPriorityInit ();    }    return retval;}IX_STATUSixAtmmDataPathUninit (IxAtmLogicalPort port){    IX_STATUS retval = IX_SUCCESS;    /*     * Uninitialize Rx Low Priority control     */    retval = ixAtmmRxLoPriorityUninit ();    if (IX_SUCCESS == retval)    {    /*     * Uninitialize Rx High Priority control     */        retval = ixAtmmRxHiPriorityUninit ();    }    if (IX_SUCCESS == retval)    {    /*     * Uninitialize Tx Done control     */        retval = ixAtmmTxDoneUninit ();    }    if (IX_SUCCESS == retval)    {    /*     * Uninitialize Tx Scheduling control     */        retval = ixAtmmTxSchedulingUninit (port);    }    return retval;}PRIVATE IX_STATUSixAtmmTxSchedulingInit (IxAtmLogicalPort port){    static BOOL firstInitDone = FALSE;        	IX_STATUS retval = IX_SUCCESS;    UINT32 i;    /* Clear InitDone flags on first initialization */    if (!firstInitDone)    {	for (i=0; i < (sizeof(ixAtmmTxSchedulingInitDone) / sizeof(BOOL)); i++)	{	    ixAtmmTxSchedulingInitDone[i] = FALSE;	}	firstInitDone = TRUE;    }    /* Only initialize each port once */    if (ixAtmmTxSchedulingInitDone[port])    {	retval =  IX_ATMM_RET_ALREADY_INITIALIZED;    }    if (retval == IX_SUCCESS)    {	/*	 * Put Atmm in scheduling mode, this registers Atmm callbacks.     	 */	retval = ixAtmdAccPortTxScheduledModeEnable (port,						     ixAtmmVcDemandUpdate,						     ixAtmmVcQueueClear,						     ixAtmmVcIdGet);    }    if (retval == IX_SUCCESS)    {	/*	 * Get depth of tx Q for case when system goes IDLE -> BUSY	 */	retval = ixAtmdAccPortTxFreeEntriesQuery (port, &ixAtmmTxQSize[port]);    }        if (retval == IX_SUCCESS)    {	/*

⌨️ 快捷键说明

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