📄 ixatmdrxcfginfo.c
字号:
/*** @file ixAtmdRxCfgInfo.c* * @author Intel Corporation* @date 17 March 2002** @brief ATM RX configuration** This module setup the different configuration elements required* to process the RX traffic** Design Notes:* This interface is designed to run under the functions of* ixAtmdAccCfgIf.c* * * @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 --*//** Sytem defined include files*//** Put the user defined include files required.*/#include "IxOsal.h"#include "IxAtmdDefines_p.h"#include "IxAtmdDescMgmt_p.h"#include "IxAtmdAssert_p.h"#include "IxAtmdUtil_p.h"#include "IxAtmdRxTransport_p.h"#include "IxAtmdRxCfgInfo_p.h"/**** @struct IxAtmdAccRxFreeQueueTable** @brief Container for Rx free queues which are initialized**/typedef struct{ IxQMgrQId rxFreeQueueId; BOOL used; unsigned int rxFreeQueueSize;} IxAtmdAccRxFreeQueueTable;static IxAtmdAccRxFreeQueueTable ixAtmdAccRxFreeQueueTable[IX_ATM_MAX_NUM_AAL_VCS];static unsigned int ixAtmdAccRxFreeQueueCount;#ifndef NDEBUG static unsigned int ixAtmdAccRxFreeDummyNotificationErrorCount;static unsigned int ixAtmdAccRxDummyProcessPerformErrorCount;static unsigned int ixAtmdAccRxEnableCount;static unsigned int ixAtmdAccRxDisableCount;#endif/* The npeResponse lock will serialise the excution of the functions* ixAtmdAccRxCfgNpeAtmStatusRead with the IxNpeMh solicited callbacks.*/static IxOsalMutex npeResponseLock;static volatile UINT32 npeRespWordRead = 0;#define IX_ATMDACC_NPE_RESPONSE_LOCK_INIT() do{\ IX_STATUS returnStatus = IX_SUCCESS;\ returnStatus = ixOsalMutexInit (&npeResponseLock);\ IX_ATMDACC_ENSURE (returnStatus == IX_SUCCESS, "Initailisation Error");\ IX_ATMDACC_NPE_RESPONSE_LOCK_GET ();\ } while(0)#define IX_ATMDACC_NPE_RESPONSE_LOCK_GET() do{\ ixOsalMutexLock (&npeResponseLock, IX_OSAL_WAIT_FOREVER);\ } while(0)#define IX_ATMDACC_NPE_RESPONSE_LOCK_RELEASE() do{\ ixOsalMutexUnlock (&npeResponseLock);\ } while(0)#define IX_ATMDACC_NPE_RESPONSE_LOCK_DESTROY() do{\ ixOsalMutexDestroy (&npeResponseLock); \ } while(0)/* function prototype */PRIVATE voidixAtmdAccRxFreeDummyNotification (IxAtmdAccUserId callbackId);PRIVATE IX_STATUSixAtmdAccRxDummyProcessPerform (IxAtmRxQueueId rxQueueId, unsigned int numberOfPdusToProcess, unsigned int *numberOfPdusProcessedPtr);PRIVATE voidixAtmdAccRxCfgChannelIdReset(IxAtmdAccRxVcDescriptor *vcDescriptorPtr);PRIVATE voidixAtmdAccRxCfgNpeAtmStatusReadCallback (IxNpeMhNpeId npeMhNpeId, IxNpeMhMessage npeMhMessage);PRIVATE IX_STATUSixAtmdAccRxCfgNpeAtmStatusRead (unsigned int * rxFreeUnderflowCount, unsigned int * rxOverflowCount);/* ---------------------------------------------------------* dummy notification*/PRIVATE voidixAtmdAccRxFreeDummyNotification (IxAtmdAccUserId callbackId){/* this function should never get called because the client* supplies its own callback. But if a disableInterrupt fails* in the qMgr (or any transient state), this function may be used.* For code efficiency, it is better to have a dummycallback (bad day* scenario) and never test a null pointer in "happy day scenarios"*/ IX_ATMDACC_FULL_STATS(ixAtmdAccRxFreeDummyNotificationErrorCount++; );}PRIVATE IX_STATUS ixAtmdAccRxDummyProcessPerform (IxAtmRxQueueId rxQueueId, unsigned int numberOfPdusToProcess, unsigned int *numberOfPdusProcessedPtr){/* this function should never get called because the client* supplies its own callback. But if a disableInterrupt fails* in the qMgr (or any transient state), this function may be used.* For code efficiency, it is better to have a dummycallback (bad day* scenario) and never test a null pointer in "happy day scenarios"*/ IX_ATMDACC_FULL_STATS( ixAtmdAccRxDummyProcessPerformErrorCount++; ); return IX_FAIL;}PRIVATE voidixAtmdAccRxCfgChannelIdReset(IxAtmdAccRxVcDescriptor *vcDescriptorPtr){ vcDescriptorPtr->connId = IX_ATMDACC_RX_INVALID_CONNID; vcDescriptorPtr->vci = NPE_INVALID_VCI; vcDescriptorPtr->vpi = NPE_INVALID_VPI; vcDescriptorPtr->port = NPE_INVALID_LOGICAL_PORT; return;}/* ---------------------------------------------------------* module initialisation*/IX_STATUSixAtmdAccRxCfgInfoInit (void){ IX_STATUS returnStatusVal = IX_SUCCESS; IxQMgrQId rxFreeQueueId; IX_STATUS status; unsigned int rxFreeQueueSize; unsigned int vc; unsigned int queueIdx; unsigned int totalRxFreeQueueSize; unsigned int averageRxFreeQueueSize; IX_ATMDACC_NPE_RESPONSE_LOCK_INIT(); /* stats reset */ ixAtmdAccRxCfgInfoStatsReset (); /* initialise the queue buffers used during Rx read */ ixOsalMemSet(ixAtmdAccRxQMgrBuffer, 0, sizeof(ixAtmdAccRxQMgrBuffer)); /* initialise the data structures */ for (vc = 0; vc < IX_ATM_MAX_NUM_AAL_OAM_RX_VCS; vc++) { ixOsalMemSet (&ixAtmdAccRxVcDescriptor[vc], 0, sizeof (IxAtmdAccRxVcDescriptor)); ixAtmdAccRxCfgChannelIdReset(&ixAtmdAccRxVcDescriptor[vc]); ixAtmdAccRxVcDescriptor[vc].status = IX_ATMDACC_RX_CHANNEL_DOWN; ixAtmdAccRxVcDescriptor[vc].rxQueueId = IX_QMGR_QUEUE_INVALID; ixAtmdAccRxVcDescriptor[vc].rxFreeQueueId = IX_QMGR_QUEUE_INVALID; ixAtmdAccRxVcDescriptor[vc].rxFreeQueueSize = IX_QMGR_Q_SIZE_INVALID; ixAtmdAccRxVcDescriptor[vc].rxFreeNotification = ixAtmdAccRxFreeDummyNotification; } /* end of for(vc) */ /* reset the Free Queue table to a default state */ for (queueIdx = 0; queueIdx < IX_ATM_MAX_NUM_AAL_VCS; queueIdx++) { ixAtmdAccRxFreeQueueTable[queueIdx].used = FALSE; ixAtmdAccRxFreeQueueTable[queueIdx].rxFreeQueueId = IX_QMGR_QUEUE_INVALID; ixAtmdAccRxFreeQueueTable[queueIdx].rxFreeQueueSize = IX_QMGR_Q_SIZE_INVALID; } /* initialize the queue mapping */ ixAtmdAccRxQMgrQId[IX_ATM_RX_A] = IX_NPE_A_QMQ_ATM_RX_HI; ixAtmdAccRxQMgrQId[IX_ATM_RX_B] = IX_NPE_A_QMQ_ATM_RX_LO; /* setup default callback */ ixAtmdAccRxUserCallback[IX_ATM_RX_A] = ixAtmdAccRxDummyProcessPerform; ixAtmdAccRxUserCallback[IX_ATM_RX_B] = ixAtmdAccRxDummyProcessPerform; /* set the RxFreeQueue table to empty */ ixAtmdAccRxFreeQueueCount = 0; /* initialise the total size of rx queues */ totalRxFreeQueueSize = 0; /* iterate through the queues Id reserved for RX free queues * to determine the details of the configured VC free queues */ for (rxFreeQueueId = IX_NPE_A_QMQ_ATM_RXFREE_MIN; rxFreeQueueId <= IX_NPE_A_QMQ_ATM_RXFREE_MAX; rxFreeQueueId++) { /* this function will fail if there are gaps in the QMgr * initialisation, which hould not break this loop. If some * queues are not initialized, the number of channels that * Atmd will be able to handle will be reduced */ status = ixQMgrQSizeInEntriesGet (rxFreeQueueId, &rxFreeQueueSize); if (status == IX_SUCCESS) { /* set this queue information in the RX Free queue table */ ixAtmdAccRxFreeQueueTable[ixAtmdAccRxFreeQueueCount].used = FALSE; ixAtmdAccRxFreeQueueTable[ixAtmdAccRxFreeQueueCount].rxFreeQueueId = rxFreeQueueId; ixAtmdAccRxFreeQueueTable[ixAtmdAccRxFreeQueueCount].rxFreeQueueSize = rxFreeQueueSize; /* keep track of how many queues are configured */ ixAtmdAccRxFreeQueueCount++; totalRxFreeQueueSize += rxFreeQueueSize; } /* end of if(status) */ } /* end of for(rxFreeQueueId) */ /* check the overall number of queues */ if (ixAtmdAccRxFreeQueueCount == 0) { /* no rx queue configured ??? */ returnStatusVal = IX_FAIL; } else { /* ensure the size of rx free queues is as expected. * This is used to prevent a misconfiguration of the descriptor pool */ averageRxFreeQueueSize = totalRxFreeQueueSize / ixAtmdAccRxFreeQueueCount; IX_ATMDACC_ABORT(averageRxFreeQueueSize <= IX_ATMDACC_AVERAGE_RXFREE_QUEUE_SIZE, "IX_ATMDACC_AVERAGE_RXFREE_QUEUE_SIZE not consistent with queue configuration"); /* no way to continue, the system configuration is wrong */ } /* end of if-else(ixAtmdAccRxFreeQueueCount) */ return returnStatusVal;}/* ---------------------------------------------------------* module uninitialisation*/IX_STATUSixAtmdAccRxCfgInfoUninit (void){ IX_ATMDACC_NPE_RESPONSE_LOCK_DESTROY(); return IX_SUCCESS;}/* ---------------------------------------------------------* data initialisation*/voidixAtmdAccRxCfgInfoStatsReset (void){ /* initialise stats */ IX_ATMDACC_FULL_STATS({ ixAtmdAccRxFreeDummyNotificationErrorCount = 0; ixAtmdAccRxDummyProcessPerformErrorCount = 0; ixAtmdAccRxEnableCount = 0; ixAtmdAccRxDisableCount = 0; ixOsalMemSet(ixAtmdAccRxDispatchStats, 0, sizeof(ixAtmdAccRxDispatchStats)); ixOsalMemSet(&ixAtmdAccRxTransportErrorStats,0,sizeof(ixAtmdAccRxTransportErrorStats)); });}/* ---------------------------------------------------------* check that the specified VC is configured*/BOOLixAtmdAccRxCfgRxVcExists (IxAtmLogicalPort port, unsigned int vpi, unsigned int vci){ BOOL result = FALSE; int vc; /* iterate through VC until found */ for (vc = 0; !result && vc < IX_ATM_MAX_NUM_AAL_OAM_RX_VCS; vc++) { if (IX_ATMDACC_RX_VC_INUSE (ixAtmdAccRxVcDescriptor[vc].connId)) { if (ixAtmdAccRxVcDescriptor[vc].vci == vci && ixAtmdAccRxVcDescriptor[vc].vpi == vpi && ixAtmdAccRxVcDescriptor[vc].port == port) { result = TRUE; } } /* end of if(IX_ATMDACC_RX_VC_INUSE) */ } /* end of for(vc) */ return result;}/* ---------------------------------------------------------* allocate a RX AAL channel for this post/vp/vc*/IX_STATUSixAtmdAccRxCfgChannelGet (IxAtmLogicalPort port, unsigned int vpi, unsigned int vci, IxAtmdAccAalType aalServiceType, unsigned int* npeVcIdPtr, IxAtmConnId* connIdPtr){ unsigned int npeVcid = 0; unsigned int limit; IX_STATUS returnStatus = IX_SUCCESS; switch( aalServiceType ) { case IX_ATMDACC_AAL5: case IX_ATMDACC_AAL0_48: case IX_ATMDACC_AAL0_52:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -