?? ixqmgrqcfg.c
字號(hào):
/** * @file QMgrQCfg.c * * @author Intel Corporation * @date 30-Oct-2001 * * @brief This modules provides an interface for setting up the static * configuration of AQM queues.This file contains the following * functions: * * * * @par * IXP400 SW Release version 2.0 * * -- Copyright Notice -- * * @par * Copyright 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 --*//* * System defined include files. *//* * User defined include files. */#include "IxOsal.h"#include "IxQMgr.h"#include "IxQMgrAqmIf_p.h"#include "IxQMgrQCfg_p.h"#include "IxQMgrDefines_p.h"/* * #defines and macros used in this file. */#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16/* Total size of SRAM */#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000/* * Check that qId is a valid queue identifier. This is provided to * make the code easier to read. */#define IX_QMGR_QID_IS_VALID(qId) \(((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))/* * Typedefs whose scope is limited to this file. *//* * This struct describes an AQM queue. * N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue * as these are requested by Access in the data path. sizeInEntries is * not required by the data path so it can be calculated dynamically. * */typedef struct{ char qName[IX_QMGR_MAX_QNAME_LEN+1]; /* Textual description of a queue*/ IxQMgrQSizeInWords qSizeInWords; /* The number of words in the queue */ IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/ BOOL isConfigured; /* This flag is TRUE if the queue has * been configured */} IxQMgrCfgQ;/* * Variable declarations global to this file. Externs are followed by * statics. */extern UINT32 * ixQMgrAqmIfQueAccRegAddr[]; /* Store data required to inline read and write access */IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];/* This pointer holds the starting address of AQM SRAM not used by * the AQM queues. */static UINT32 freeSramAddress=0;/* 4 words of zeroed memory for inline access */static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };static BOOL cfgInitialized = FALSE;static IxOsalMutex ixQMgrQCfgMutex;/* * Statistics */static IxQMgrQCfgStats stats;/* * Function declarations */PRIVATE BOOLwatermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);PRIVATE BOOLqSizeInWordsIsOk (IxQMgrQSizeInWords qSize);PRIVATE BOOLqEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);/* * Function definitions. */voidixQMgrQCfgInit (void){ int loopIndex; for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++) { /* info for code inlining */ ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder; /* info for code inlining */ ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder; ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder; ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0; ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder; } /* Initialise the AqmIf component */ ixQMgrAqmIfInit (); /* Reset all queues to have queue name = NULL, entry size = 0 and * isConfigured = false */ for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++) { strcpy (cfgQueueInfo[loopIndex].qName, ""); cfgQueueInfo[loopIndex].qSizeInWords = 0; cfgQueueInfo[loopIndex].qEntrySizeInWords = 0; cfgQueueInfo[loopIndex].isConfigured = FALSE; /* Statistics */ stats.qStats[loopIndex].isConfigured = FALSE; stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName; } /* Statistics */ stats.wmSetCnt = 0; ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress); ixOsalMutexInit(&ixQMgrQCfgMutex); cfgInitialized = TRUE;}voidixQMgrQCfgUninit (void){ cfgInitialized = FALSE; /* Uninitialise the AqmIf component */ ixQMgrAqmIfUninit ();}IX_STATUSixQMgrQConfig (char *qName, IxQMgrQId qId, IxQMgrQSizeInWords qSizeInWords, IxQMgrQEntrySizeInWords qEntrySizeInWords){ UINT32 aqmLocalBaseAddress; if (!cfgInitialized) { return IX_FAIL; } if (!IX_QMGR_QID_IS_VALID(qId)) { return IX_QMGR_INVALID_Q_ID; } else if (NULL == qName) { return IX_QMGR_PARAMETER_ERROR; } else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN) { return IX_QMGR_PARAMETER_ERROR; } else if (!qSizeInWordsIsOk (qSizeInWords)) { return IX_QMGR_INVALID_QSIZE; } else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords)) { return IX_QMGR_INVALID_Q_ENTRY_SIZE; } else if (cfgQueueInfo[qId].isConfigured) { return IX_QMGR_Q_ALREADY_CONFIGURED; } ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER); /* Write the config register */ ixQMgrAqmIfQueCfgWrite (qId, qSizeInWords, qEntrySizeInWords, freeSramAddress); strcpy (cfgQueueInfo[qId].qName, qName); cfgQueueInfo[qId].qSizeInWords = qSizeInWords; cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords; /* store pre-computed information in the same cache line * to facilitate inlining of QRead and QWrite functions * in IxQMgr.h */ ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0; ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0; ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords; ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries = (UINT32)qSizeInWords / (UINT32)qEntrySizeInWords; /* Calculate the new freeSramAddress from the size of the queue * currently being configured. */ freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD); /* Get the virtual SRAM address */ ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress); IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <= IX_QMGR_QUE_BUFFER_SPACE_SIZE); /* The queue is now configured */ cfgQueueInfo[qId].isConfigured = TRUE; ixOsalMutexUnlock(&ixQMgrQCfgMutex);#ifndef NDEBUG /* Update statistics */ stats.qStats[qId].isConfigured = TRUE; stats.qStats[qId].qName = cfgQueueInfo[qId].qName;#endif return IX_SUCCESS;}IxQMgrQSizeInWordsixQMgrQSizeInWordsGet (IxQMgrQId qId){ /* No parameter checking as this is used on the data path */ return (cfgQueueInfo[qId].qSizeInWords);}IX_STATUSixQMgrQSizeInEntriesGet (IxQMgrQId qId, unsigned *qSizeInEntries){ if (!ixQMgrQIsConfigured(qId)) { return IX_QMGR_Q_NOT_CONFIGURED; } if(NULL == qSizeInEntries) { return IX_QMGR_PARAMETER_ERROR; } *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) / (UINT32)cfgQueueInfo[qId].qEntrySizeInWords; return IX_SUCCESS;}IxQMgrQEntrySizeInWordsixQMgrQEntrySizeInWordsGet (IxQMgrQId qId){ /* No parameter checking as this is used on the data path */ return (cfgQueueInfo[qId].qEntrySizeInWords);}IX_STATUSixQMgrWatermarkSet (IxQMgrQId qId, IxQMgrWMLevel ne, IxQMgrWMLevel nf){ IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */ IxQMgrQStatus qStatusOnExit; /* to this function */ if (!ixQMgrQIsConfigured(qId)) { return IX_QMGR_Q_NOT_CONFIGURED; } if (!watermarkLevelIsOk (qId, ne)) { return IX_QMGR_INVALID_Q_WM; } if (!watermarkLevelIsOk (qId, nf)) { return IX_QMGR_INVALID_Q_WM; } /* Get the current queue status */ ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);#ifndef NDEBUG /* Update statistics */ stats.wmSetCnt++;#endif ixQMgrAqmIfWatermarkSet (qId, ne, nf); /* Get the current queue status */ ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit); /* If the status has changed return a warning */ if (qStatusOnEntry != qStatusOnExit) { return IX_QMGR_WARNING; } return IX_SUCCESS;}IX_STATUSixQMgrAvailableSramAddressGet (UINT32 *address, unsigned *sizeOfFreeRam){ UINT32 aqmLocalBaseAddress; if ((NULL == address)||(NULL == sizeOfFreeRam)) { return IX_QMGR_PARAMETER_ERROR; } if (!cfgInitialized) { return IX_FAIL; } *address = freeSramAddress; /* Get the virtual SRAM address */ ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress); /* * Calculate the size in bytes of free sram * i.e. current free SRAM virtual pointer from * (base + total size) */ *sizeOfFreeRam = (aqmLocalBaseAddress + IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) - freeSramAddress; if (0 == *sizeOfFreeRam) { return IX_QMGR_NO_AVAILABLE_SRAM; } return IX_SUCCESS;}BOOLixQMgrQIsConfigured (IxQMgrQId qId){ if (!IX_QMGR_QID_IS_VALID(qId)) { return FALSE; } return cfgQueueInfo[qId].isConfigured;}IxQMgrQCfgStats*ixQMgrQCfgStatsGet (void){ return &stats;}IxQMgrQCfgStats*ixQMgrQCfgQStatsGet (IxQMgrQId qId){ unsigned int ne; unsigned int nf; UINT32 baseAddress; UINT32 readPtr; UINT32 writePtr; stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords; stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords; if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries)) { if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries)) { IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId); } } ixQMgrAqmIfQueCfgRead (qId, stats.qStats[qId].numEntries, &baseAddress, &ne, &nf, &readPtr, &writePtr); stats.qStats[qId].baseAddress = baseAddress; stats.qStats[qId].ne = ne; stats.qStats[qId].nf = nf; stats.qStats[qId].readPtr = readPtr; stats.qStats[qId].writePtr = writePtr; return &stats;}/* * Static function definitions */PRIVATE BOOLwatermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level){ unsigned qSizeInEntries; switch (level) { case IX_QMGR_Q_WM_LEVEL0: case IX_QMGR_Q_WM_LEVEL1: case IX_QMGR_Q_WM_LEVEL2: case IX_QMGR_Q_WM_LEVEL4: case IX_QMGR_Q_WM_LEVEL8: case IX_QMGR_Q_WM_LEVEL16: case IX_QMGR_Q_WM_LEVEL32: case IX_QMGR_Q_WM_LEVEL64: break; default: return FALSE; } /* Check watermark is not bigger than the qSizeInEntries */ ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries); if ((unsigned)level > qSizeInEntries) { return FALSE; } return TRUE;}PRIVATE BOOLqSizeInWordsIsOk (IxQMgrQSizeInWords qSize){ BOOL status; switch (qSize) { case IX_QMGR_Q_SIZE16: case IX_QMGR_Q_SIZE32: case IX_QMGR_Q_SIZE64: case IX_QMGR_Q_SIZE128: status = TRUE; break; default: status = FALSE; break; } return status;}PRIVATE BOOLqEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize){ BOOL status; switch (entrySize) { case IX_QMGR_Q_ENTRY_SIZE1: case IX_QMGR_Q_ENTRY_SIZE2: case IX_QMGR_Q_ENTRY_SIZE4: status = TRUE; break; default: status = FALSE; break; } return status;}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -