4 * @author Intel Corporation
7 * @brief This modules provides an interface for setting up the static
8 * configuration of AQM queues.This file contains the following
14 * IXP400 SW Release version 2.0
16 * -- Copyright Notice --
19 * Copyright 2001-2005, Intel Corporation.
20 * All rights reserved.
23 * SPDX-License-Identifier: BSD-3-Clause
25 * -- End of Copyright Notice --
29 * System defined include files.
33 * User defined include files.
37 #include "IxQMgrAqmIf_p.h"
38 #include "IxQMgrQCfg_p.h"
39 #include "IxQMgrDefines_p.h"
42 * #defines and macros used in this file.
45 #define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
47 /* Total size of SRAM */
48 #define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
51 * Check that qId is a valid queue identifier. This is provided to
52 * make the code easier to read.
54 #define IX_QMGR_QID_IS_VALID(qId) \
55 (((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))
58 * Typedefs whose scope is limited to this file.
62 * This struct describes an AQM queue.
63 * N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue
64 * as these are requested by Access in the data path. sizeInEntries is
65 * not required by the data path so it can be calculated dynamically.
70 char qName[IX_QMGR_MAX_QNAME_LEN+1]; /* Textual description of a queue*/
71 IxQMgrQSizeInWords qSizeInWords; /* The number of words in the queue */
72 IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/
73 BOOL isConfigured; /* This flag is true if the queue has
79 * Variable declarations global to this file. Externs are followed by
83 extern UINT32 * ixQMgrAqmIfQueAccRegAddr[];
85 /* Store data required to inline read and write access
87 IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];
89 static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];
91 /* This pointer holds the starting address of AQM SRAM not used by
94 static UINT32 freeSramAddress=0;
96 /* 4 words of zeroed memory for inline access */
97 static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };
99 static BOOL cfgInitialized = false;
101 static IxOsalMutex ixQMgrQCfgMutex;
106 static IxQMgrQCfgStats stats;
109 * Function declarations
112 watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);
115 qSizeInWordsIsOk (IxQMgrQSizeInWords qSize);
118 qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);
121 * Function definitions.
124 ixQMgrQCfgInit (void)
128 for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
130 /* info for code inlining */
131 ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder;
133 /* info for code inlining */
134 ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0;
135 ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0;
136 ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder;
137 ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder;
138 ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0;
139 ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0;
140 ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0;
141 ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0;
142 ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder;
145 /* Initialise the AqmIf component */
148 /* Reset all queues to have queue name = NULL, entry size = 0 and
149 * isConfigured = false
151 for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
153 strcpy (cfgQueueInfo[loopIndex].qName, "");
154 cfgQueueInfo[loopIndex].qSizeInWords = 0;
155 cfgQueueInfo[loopIndex].qEntrySizeInWords = 0;
156 cfgQueueInfo[loopIndex].isConfigured = false;
159 stats.qStats[loopIndex].isConfigured = false;
160 stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName;
166 ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress);
168 ixOsalMutexInit(&ixQMgrQCfgMutex);
170 cfgInitialized = true;
174 ixQMgrQCfgUninit (void)
176 cfgInitialized = false;
178 /* Uninitialise the AqmIf component */
179 ixQMgrAqmIfUninit ();
183 ixQMgrQConfig (char *qName,
185 IxQMgrQSizeInWords qSizeInWords,
186 IxQMgrQEntrySizeInWords qEntrySizeInWords)
188 UINT32 aqmLocalBaseAddress;
195 if (!IX_QMGR_QID_IS_VALID(qId))
197 return IX_QMGR_INVALID_Q_ID;
200 else if (NULL == qName)
202 return IX_QMGR_PARAMETER_ERROR;
205 else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN)
207 return IX_QMGR_PARAMETER_ERROR;
210 else if (!qSizeInWordsIsOk (qSizeInWords))
212 return IX_QMGR_INVALID_QSIZE;
215 else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords))
217 return IX_QMGR_INVALID_Q_ENTRY_SIZE;
220 else if (cfgQueueInfo[qId].isConfigured)
222 return IX_QMGR_Q_ALREADY_CONFIGURED;
225 ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER);
227 /* Write the config register */
228 ixQMgrAqmIfQueCfgWrite (qId,
234 strcpy (cfgQueueInfo[qId].qName, qName);
235 cfgQueueInfo[qId].qSizeInWords = qSizeInWords;
236 cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
238 /* store pre-computed information in the same cache line
239 * to facilitate inlining of QRead and QWrite functions
242 ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0;
243 ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0;
244 ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
245 ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries =
246 (UINT32)qSizeInWords / (UINT32)qEntrySizeInWords;
248 /* Calculate the new freeSramAddress from the size of the queue
249 * currently being configured.
251 freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD);
253 /* Get the virtual SRAM address */
254 ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
256 IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <=
257 IX_QMGR_QUE_BUFFER_SPACE_SIZE);
259 /* The queue is now configured */
260 cfgQueueInfo[qId].isConfigured = true;
262 ixOsalMutexUnlock(&ixQMgrQCfgMutex);
265 /* Update statistics */
266 stats.qStats[qId].isConfigured = true;
267 stats.qStats[qId].qName = cfgQueueInfo[qId].qName;
273 ixQMgrQSizeInWordsGet (IxQMgrQId qId)
275 /* No parameter checking as this is used on the data path */
276 return (cfgQueueInfo[qId].qSizeInWords);
280 ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
281 unsigned *qSizeInEntries)
283 if (!ixQMgrQIsConfigured(qId))
285 return IX_QMGR_Q_NOT_CONFIGURED;
288 if(NULL == qSizeInEntries)
290 return IX_QMGR_PARAMETER_ERROR;
293 *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) /
294 (UINT32)cfgQueueInfo[qId].qEntrySizeInWords;
299 IxQMgrQEntrySizeInWords
300 ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId)
302 /* No parameter checking as this is used on the data path */
303 return (cfgQueueInfo[qId].qEntrySizeInWords);
307 ixQMgrWatermarkSet (IxQMgrQId qId,
311 IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
312 IxQMgrQStatus qStatusOnExit; /* to this function */
314 if (!ixQMgrQIsConfigured(qId))
316 return IX_QMGR_Q_NOT_CONFIGURED;
319 if (!watermarkLevelIsOk (qId, ne))
321 return IX_QMGR_INVALID_Q_WM;
324 if (!watermarkLevelIsOk (qId, nf))
326 return IX_QMGR_INVALID_Q_WM;
329 /* Get the current queue status */
330 ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
333 /* Update statistics */
337 ixQMgrAqmIfWatermarkSet (qId,
341 /* Get the current queue status */
342 ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
344 /* If the status has changed return a warning */
345 if (qStatusOnEntry != qStatusOnExit)
347 return IX_QMGR_WARNING;
354 ixQMgrAvailableSramAddressGet (UINT32 *address,
355 unsigned *sizeOfFreeRam)
357 UINT32 aqmLocalBaseAddress;
359 if ((NULL == address)||(NULL == sizeOfFreeRam))
361 return IX_QMGR_PARAMETER_ERROR;
368 *address = freeSramAddress;
370 /* Get the virtual SRAM address */
371 ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
374 * Calculate the size in bytes of free sram
375 * i.e. current free SRAM virtual pointer from
376 * (base + total size)
379 (aqmLocalBaseAddress +
380 IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) -
383 if (0 == *sizeOfFreeRam)
385 return IX_QMGR_NO_AVAILABLE_SRAM;
392 ixQMgrQIsConfigured (IxQMgrQId qId)
394 if (!IX_QMGR_QID_IS_VALID(qId))
399 return cfgQueueInfo[qId].isConfigured;
403 ixQMgrQCfgStatsGet (void)
409 ixQMgrQCfgQStatsGet (IxQMgrQId qId)
417 stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords;
418 stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords;
420 if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
422 if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
424 IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId);
428 ixQMgrAqmIfQueCfgRead (qId,
429 stats.qStats[qId].numEntries,
436 stats.qStats[qId].baseAddress = baseAddress;
437 stats.qStats[qId].ne = ne;
438 stats.qStats[qId].nf = nf;
439 stats.qStats[qId].readPtr = readPtr;
440 stats.qStats[qId].writePtr = writePtr;
446 * Static function definitions
450 watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level)
452 unsigned qSizeInEntries;
456 case IX_QMGR_Q_WM_LEVEL0:
457 case IX_QMGR_Q_WM_LEVEL1:
458 case IX_QMGR_Q_WM_LEVEL2:
459 case IX_QMGR_Q_WM_LEVEL4:
460 case IX_QMGR_Q_WM_LEVEL8:
461 case IX_QMGR_Q_WM_LEVEL16:
462 case IX_QMGR_Q_WM_LEVEL32:
463 case IX_QMGR_Q_WM_LEVEL64:
469 /* Check watermark is not bigger than the qSizeInEntries */
470 ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries);
472 if ((unsigned)level > qSizeInEntries)
481 qSizeInWordsIsOk (IxQMgrQSizeInWords qSize)
487 case IX_QMGR_Q_SIZE16:
488 case IX_QMGR_Q_SIZE32:
489 case IX_QMGR_Q_SIZE64:
490 case IX_QMGR_Q_SIZE128:
502 qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize)
508 case IX_QMGR_Q_ENTRY_SIZE1:
509 case IX_QMGR_Q_ENTRY_SIZE2:
510 case IX_QMGR_Q_ENTRY_SIZE4: