source: SVN/rincon/u-boot/cpu/ixp/npe/IxQMgrQCfg.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 13.0 KB
Line 
1/**
2 * @file    QMgrQCfg.c
3 *
4 * @author Intel Corporation
5 * @date    30-Oct-2001
6 *
7 * @brief   This modules provides an interface for setting up the static
8 * configuration of AQM queues.This file contains the following
9 * functions:
10 *
11 *
12 *
13 * @par
14 * IXP400 SW Release version 2.0
15 *
16 * -- Copyright Notice --
17 *
18 * @par
19 * Copyright 2001-2005, Intel Corporation.
20 * All rights reserved.
21 *
22 * @par
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the above copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. Neither the name of the Intel Corporation nor the names of its contributors
32 *    may be used to endorse or promote products derived from this software
33 *    without specific prior written permission.
34 *
35 * @par
36 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
37 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 *
48 * @par
49 * -- End of Copyright Notice --
50*/
51
52/*
53 * System defined include files.
54 */
55
56/*
57 * User defined include files.
58 */
59#include "IxOsal.h"
60#include "IxQMgr.h"
61#include "IxQMgrAqmIf_p.h"
62#include "IxQMgrQCfg_p.h"
63#include "IxQMgrDefines_p.h"
64
65/*
66 * #defines and macros used in this file.
67 */
68
69#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
70
71/* Total size of SRAM */
72#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
73
74/*
75 * Check that qId is a valid queue identifier. This is provided to
76 * make the code easier to read.
77 */
78#define IX_QMGR_QID_IS_VALID(qId) \
79(((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))
80
81/*
82 * Typedefs whose scope is limited to this file.
83 */
84
85/*
86 * This struct describes an AQM queue.
87 * N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue
88 * as these are requested by Access in the data path. sizeInEntries is
89 * not required by the data path so it can be calculated dynamically.
90 *
91 */
92typedef struct
93{
94    char qName[IX_QMGR_MAX_QNAME_LEN+1];       /* Textual description of a queue*/
95    IxQMgrQSizeInWords qSizeInWords;           /* The number of words in the queue */
96    IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/
97    BOOL isConfigured;                         /* This flag is TRUE if the queue has
98                                                *   been configured
99                                                */
100} IxQMgrCfgQ;
101
102/*
103 * Variable declarations global to this file. Externs are followed by
104 * statics.
105 */
106
107extern UINT32 * ixQMgrAqmIfQueAccRegAddr[]; 
108
109/* Store data required to inline read and write access
110 */
111IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];
112
113static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];
114
115/* This pointer holds the starting address of AQM SRAM not used by
116 * the AQM queues.
117 */
118static UINT32 freeSramAddress=0;
119
120/* 4 words of zeroed memory for inline access */
121static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };
122
123static BOOL cfgInitialized = FALSE;
124
125static IxOsalMutex ixQMgrQCfgMutex;
126
127/*
128 * Statistics
129 */
130static IxQMgrQCfgStats stats;
131
132/*
133 * Function declarations
134 */
135PRIVATE BOOL
136watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);
137
138PRIVATE BOOL
139qSizeInWordsIsOk (IxQMgrQSizeInWords qSize);
140
141PRIVATE BOOL
142qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);
143
144/*
145 * Function definitions.
146 */
147void
148ixQMgrQCfgInit (void)
149{
150    int loopIndex;
151   
152    for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
153    {
154        /* info for code inlining */
155        ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder;
156
157        /* info for code inlining */
158        ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0;
159        ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0;
160        ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder;
161        ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder;
162        ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0;
163        ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0;
164        ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0;
165        ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0;
166        ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder;
167   }
168
169    /* Initialise the AqmIf component */
170    ixQMgrAqmIfInit ();
171   
172    /* Reset all queues to have queue name = NULL, entry size = 0 and
173     * isConfigured = false
174     */
175    for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
176    {
177        strcpy (cfgQueueInfo[loopIndex].qName, "");
178        cfgQueueInfo[loopIndex].qSizeInWords = 0;
179        cfgQueueInfo[loopIndex].qEntrySizeInWords = 0;
180        cfgQueueInfo[loopIndex].isConfigured = FALSE;
181
182        /* Statistics */
183        stats.qStats[loopIndex].isConfigured = FALSE;
184        stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName;
185    }
186
187    /* Statistics */
188    stats.wmSetCnt = 0;
189
190    ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress);
191   
192    ixOsalMutexInit(&ixQMgrQCfgMutex);
193
194    cfgInitialized = TRUE;
195}
196
197void
198ixQMgrQCfgUninit (void)
199{
200    cfgInitialized = FALSE;
201
202    /* Uninitialise the AqmIf component */
203    ixQMgrAqmIfUninit ();
204}
205
206IX_STATUS
207ixQMgrQConfig (char *qName,
208              IxQMgrQId qId,
209              IxQMgrQSizeInWords qSizeInWords,
210              IxQMgrQEntrySizeInWords qEntrySizeInWords)
211{
212    UINT32 aqmLocalBaseAddress;
213
214    if (!cfgInitialized)
215    {
216        return IX_FAIL;
217    }
218   
219    if (!IX_QMGR_QID_IS_VALID(qId))
220    {
221        return IX_QMGR_INVALID_Q_ID;
222    }
223   
224    else if (NULL == qName)
225    {
226        return IX_QMGR_PARAMETER_ERROR;
227    }
228   
229    else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN)
230    {
231        return IX_QMGR_PARAMETER_ERROR;
232    }
233
234    else if (!qSizeInWordsIsOk (qSizeInWords))
235    {
236        return IX_QMGR_INVALID_QSIZE;
237    }
238
239    else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords))
240    {
241        return IX_QMGR_INVALID_Q_ENTRY_SIZE;
242    }
243   
244    else if (cfgQueueInfo[qId].isConfigured)
245    {
246        return IX_QMGR_Q_ALREADY_CONFIGURED;
247    }
248   
249    ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER);
250
251    /* Write the config register */
252    ixQMgrAqmIfQueCfgWrite (qId,
253                           qSizeInWords,
254                           qEntrySizeInWords,
255                           freeSramAddress);
256
257
258    strcpy (cfgQueueInfo[qId].qName, qName);
259    cfgQueueInfo[qId].qSizeInWords = qSizeInWords;
260    cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
261
262    /* store pre-computed information in the same cache line
263     * to facilitate inlining of QRead and QWrite functions
264     * in IxQMgr.h
265     */
266    ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0;
267    ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0;
268    ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
269    ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries = 
270                (UINT32)qSizeInWords / (UINT32)qEntrySizeInWords;
271
272    /* Calculate the new freeSramAddress from the size of the queue
273     * currently being configured.
274     */
275    freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD);
276
277    /* Get the virtual SRAM address */
278    ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
279
280    IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <=
281              IX_QMGR_QUE_BUFFER_SPACE_SIZE);
282
283    /* The queue is now configured */
284    cfgQueueInfo[qId].isConfigured = TRUE;
285
286    ixOsalMutexUnlock(&ixQMgrQCfgMutex);
287
288#ifndef NDEBUG
289    /* Update statistics */
290    stats.qStats[qId].isConfigured = TRUE;
291    stats.qStats[qId].qName = cfgQueueInfo[qId].qName;
292#endif
293    return IX_SUCCESS;
294}
295
296IxQMgrQSizeInWords
297ixQMgrQSizeInWordsGet (IxQMgrQId qId)
298{
299    /* No parameter checking as this is used on the data path */
300    return (cfgQueueInfo[qId].qSizeInWords);
301}
302
303IX_STATUS
304ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
305                         unsigned *qSizeInEntries)
306{
307    if (!ixQMgrQIsConfigured(qId))
308    {
309        return IX_QMGR_Q_NOT_CONFIGURED;
310    }
311
312    if(NULL == qSizeInEntries)
313    {
314        return IX_QMGR_PARAMETER_ERROR;
315    }
316
317    *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) /
318        (UINT32)cfgQueueInfo[qId].qEntrySizeInWords;
319
320    return IX_SUCCESS;
321}
322
323IxQMgrQEntrySizeInWords
324ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId)
325{
326    /* No parameter checking as this is used on the data path */
327    return (cfgQueueInfo[qId].qEntrySizeInWords);
328}
329
330IX_STATUS
331ixQMgrWatermarkSet (IxQMgrQId qId,
332                    IxQMgrWMLevel ne,
333                    IxQMgrWMLevel nf)
334{   
335    IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
336    IxQMgrQStatus qStatusOnExit; /* to this function               */
337
338    if (!ixQMgrQIsConfigured(qId))
339    {
340        return IX_QMGR_Q_NOT_CONFIGURED;
341    }
342
343    if (!watermarkLevelIsOk (qId, ne))
344    {
345        return IX_QMGR_INVALID_Q_WM;
346    }
347
348    if (!watermarkLevelIsOk (qId, nf))
349    {
350        return IX_QMGR_INVALID_Q_WM;
351    }
352
353    /* Get the current queue status */
354    ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
355
356#ifndef NDEBUG
357    /* Update statistics */
358    stats.wmSetCnt++;
359#endif
360
361    ixQMgrAqmIfWatermarkSet (qId,
362                            ne,
363                            nf);
364
365    /* Get the current queue status */
366    ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
367 
368    /* If the status has changed return a warning */
369    if (qStatusOnEntry != qStatusOnExit)
370    {
371        return IX_QMGR_WARNING;
372    }
373
374    return IX_SUCCESS;
375}
376
377IX_STATUS
378ixQMgrAvailableSramAddressGet (UINT32 *address,
379                              unsigned *sizeOfFreeRam)
380{
381    UINT32 aqmLocalBaseAddress;
382
383    if ((NULL == address)||(NULL == sizeOfFreeRam)) 
384    {
385        return IX_QMGR_PARAMETER_ERROR;
386    }
387    if (!cfgInitialized)
388    {
389        return IX_FAIL;
390    }
391
392    *address = freeSramAddress;
393
394    /* Get the virtual SRAM address */
395    ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
396
397    /*
398     * Calculate the size in bytes of free sram
399     * i.e. current free SRAM virtual pointer from
400     *      (base + total size)
401     */
402    *sizeOfFreeRam = 
403        (aqmLocalBaseAddress +
404        IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) -
405        freeSramAddress;
406
407    if (0 == *sizeOfFreeRam)
408    {
409        return IX_QMGR_NO_AVAILABLE_SRAM;
410    }
411
412    return IX_SUCCESS;
413}
414
415BOOL
416ixQMgrQIsConfigured (IxQMgrQId qId)
417{
418    if (!IX_QMGR_QID_IS_VALID(qId))
419    {
420        return FALSE;
421    }
422
423    return cfgQueueInfo[qId].isConfigured;
424}
425
426IxQMgrQCfgStats*
427ixQMgrQCfgStatsGet (void)
428{
429    return &stats;
430}
431
432IxQMgrQCfgStats*
433ixQMgrQCfgQStatsGet (IxQMgrQId qId)
434{
435    unsigned int ne;
436    unsigned int nf;
437    UINT32 baseAddress;
438    UINT32 readPtr;
439    UINT32 writePtr;
440
441    stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords;
442    stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords;
443   
444    if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
445    {
446        if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
447        {
448           IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId);
449        }
450    }
451
452    ixQMgrAqmIfQueCfgRead (qId,
453                           stats.qStats[qId].numEntries,
454                           &baseAddress,
455                           &ne,
456                           &nf,
457                           &readPtr,
458                           &writePtr);
459       
460    stats.qStats[qId].baseAddress = baseAddress;
461    stats.qStats[qId].ne = ne;
462    stats.qStats[qId].nf = nf;
463    stats.qStats[qId].readPtr = readPtr;
464    stats.qStats[qId].writePtr = writePtr;
465
466    return &stats;
467}
468
469/*
470 * Static function definitions
471 */
472
473PRIVATE BOOL
474watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level)
475{
476    unsigned qSizeInEntries;
477
478    switch (level)
479    {
480        case IX_QMGR_Q_WM_LEVEL0: 
481        case IX_QMGR_Q_WM_LEVEL1: 
482        case IX_QMGR_Q_WM_LEVEL2: 
483        case IX_QMGR_Q_WM_LEVEL4: 
484        case IX_QMGR_Q_WM_LEVEL8: 
485        case IX_QMGR_Q_WM_LEVEL16:
486        case IX_QMGR_Q_WM_LEVEL32:
487        case IX_QMGR_Q_WM_LEVEL64:
488            break;
489        default:
490            return FALSE;
491    }
492
493    /* Check watermark is not bigger than the qSizeInEntries */
494    ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries);
495
496    if ((unsigned)level > qSizeInEntries)
497    {
498        return FALSE;
499    }
500
501    return TRUE;
502}
503
504PRIVATE BOOL
505qSizeInWordsIsOk (IxQMgrQSizeInWords qSize)
506{
507    BOOL status;
508
509    switch (qSize)
510    {   
511        case IX_QMGR_Q_SIZE16:
512        case IX_QMGR_Q_SIZE32:
513        case IX_QMGR_Q_SIZE64:
514        case IX_QMGR_Q_SIZE128:
515            status = TRUE;
516            break;
517        default:
518            status = FALSE;
519            break;
520    }
521
522    return status;
523}
524
525PRIVATE BOOL
526qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize)
527{
528    BOOL status;
529
530    switch (entrySize)
531    {
532        case IX_QMGR_Q_ENTRY_SIZE1:
533        case IX_QMGR_Q_ENTRY_SIZE2:
534        case IX_QMGR_Q_ENTRY_SIZE4:
535            status = TRUE;
536            break;
537        default:
538            status = FALSE;
539            break;
540    }
541
542    return status;
543}
Note: See TracBrowser for help on using the repository browser.