]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/npe/IxQMgrQCfg.c
imx6 SION bit has to be on for the pins that are used as ENET_REF_CLK
[karo-tx-uboot.git] / drivers / net / npe / IxQMgrQCfg.c
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  * SPDX-License-Identifier:     BSD-3-Clause
24  * @par
25  * -- End of Copyright Notice --
26 */
27
28 /*
29  * System defined include files.
30  */
31
32 /*
33  * User defined include files.
34  */
35 #include "IxOsal.h"
36 #include "IxQMgr.h"
37 #include "IxQMgrAqmIf_p.h"
38 #include "IxQMgrQCfg_p.h"
39 #include "IxQMgrDefines_p.h"
40
41 /*
42  * #defines and macros used in this file.
43  */
44
45 #define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
46
47 /* Total size of SRAM */
48 #define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
49
50 /*
51  * Check that qId is a valid queue identifier. This is provided to
52  * make the code easier to read.
53  */
54 #define IX_QMGR_QID_IS_VALID(qId) \
55 (((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))
56
57 /*
58  * Typedefs whose scope is limited to this file.
59  */
60
61 /*
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.
66  * 
67  */
68 typedef struct
69 {
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
74                                                 *   been configured
75                                                 */
76 } IxQMgrCfgQ;
77
78 /*
79  * Variable declarations global to this file. Externs are followed by
80  * statics.
81  */
82
83 extern UINT32 * ixQMgrAqmIfQueAccRegAddr[]; 
84
85 /* Store data required to inline read and write access
86  */
87 IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];
88
89 static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];
90
91 /* This pointer holds the starting address of AQM SRAM not used by
92  * the AQM queues.
93  */
94 static UINT32 freeSramAddress=0;
95
96 /* 4 words of zeroed memory for inline access */
97 static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };
98
99 static BOOL cfgInitialized = false;
100
101 static IxOsalMutex ixQMgrQCfgMutex;
102
103 /*
104  * Statistics
105  */
106 static IxQMgrQCfgStats stats;
107
108 /*
109  * Function declarations
110  */
111 PRIVATE BOOL
112 watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);
113
114 PRIVATE BOOL
115 qSizeInWordsIsOk (IxQMgrQSizeInWords qSize);
116
117 PRIVATE BOOL
118 qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);
119
120 /*
121  * Function definitions.
122  */
123 void
124 ixQMgrQCfgInit (void)
125 {
126     int loopIndex;
127     
128     for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
129     {
130         /* info for code inlining */
131         ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder;
132
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;
143    }
144
145     /* Initialise the AqmIf component */
146     ixQMgrAqmIfInit ();
147    
148     /* Reset all queues to have queue name = NULL, entry size = 0 and
149      * isConfigured = false
150      */
151     for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
152     {
153         strcpy (cfgQueueInfo[loopIndex].qName, "");
154         cfgQueueInfo[loopIndex].qSizeInWords = 0;
155         cfgQueueInfo[loopIndex].qEntrySizeInWords = 0;
156         cfgQueueInfo[loopIndex].isConfigured = false;
157
158         /* Statistics */
159         stats.qStats[loopIndex].isConfigured = false;
160         stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName;
161     }
162
163     /* Statistics */
164     stats.wmSetCnt = 0;
165
166     ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress);
167     
168     ixOsalMutexInit(&ixQMgrQCfgMutex);
169
170     cfgInitialized = true;
171 }
172
173 void
174 ixQMgrQCfgUninit (void)
175 {
176     cfgInitialized = false;
177
178     /* Uninitialise the AqmIf component */
179     ixQMgrAqmIfUninit ();
180 }
181
182 IX_STATUS
183 ixQMgrQConfig (char *qName,
184               IxQMgrQId qId,
185               IxQMgrQSizeInWords qSizeInWords,
186               IxQMgrQEntrySizeInWords qEntrySizeInWords)
187 {
188     UINT32 aqmLocalBaseAddress;
189
190     if (!cfgInitialized)
191     {
192         return IX_FAIL;
193     }
194     
195     if (!IX_QMGR_QID_IS_VALID(qId))
196     {
197         return IX_QMGR_INVALID_Q_ID;
198     }
199     
200     else if (NULL == qName)
201     {
202         return IX_QMGR_PARAMETER_ERROR;
203     }
204     
205     else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN)
206     {
207         return IX_QMGR_PARAMETER_ERROR;
208     }
209
210     else if (!qSizeInWordsIsOk (qSizeInWords))
211     {
212         return IX_QMGR_INVALID_QSIZE;
213     }
214
215     else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords))
216     {
217         return IX_QMGR_INVALID_Q_ENTRY_SIZE;
218     }
219     
220     else if (cfgQueueInfo[qId].isConfigured)
221     {
222         return IX_QMGR_Q_ALREADY_CONFIGURED;
223     }
224    
225     ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER);
226
227     /* Write the config register */
228     ixQMgrAqmIfQueCfgWrite (qId,
229                            qSizeInWords,
230                            qEntrySizeInWords,
231                            freeSramAddress);
232
233
234     strcpy (cfgQueueInfo[qId].qName, qName);
235     cfgQueueInfo[qId].qSizeInWords = qSizeInWords;
236     cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
237
238     /* store pre-computed information in the same cache line
239      * to facilitate inlining of QRead and QWrite functions 
240      * in IxQMgr.h
241      */
242     ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0;
243     ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0;
244     ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
245     ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries = 
246                 (UINT32)qSizeInWords / (UINT32)qEntrySizeInWords;
247
248     /* Calculate the new freeSramAddress from the size of the queue
249      * currently being configured.
250      */
251     freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD);
252
253     /* Get the virtual SRAM address */
254     ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
255
256     IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <=
257               IX_QMGR_QUE_BUFFER_SPACE_SIZE);
258
259     /* The queue is now configured */
260     cfgQueueInfo[qId].isConfigured = true;
261
262     ixOsalMutexUnlock(&ixQMgrQCfgMutex);
263
264 #ifndef NDEBUG
265     /* Update statistics */
266     stats.qStats[qId].isConfigured = true;
267     stats.qStats[qId].qName = cfgQueueInfo[qId].qName;
268 #endif
269     return IX_SUCCESS;
270 }
271
272 IxQMgrQSizeInWords
273 ixQMgrQSizeInWordsGet (IxQMgrQId qId)
274 {
275     /* No parameter checking as this is used on the data path */
276     return (cfgQueueInfo[qId].qSizeInWords);
277 }
278
279 IX_STATUS
280 ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
281                          unsigned *qSizeInEntries)
282 {
283     if (!ixQMgrQIsConfigured(qId))
284     {
285         return IX_QMGR_Q_NOT_CONFIGURED;
286     }
287
288     if(NULL == qSizeInEntries)
289     {
290         return IX_QMGR_PARAMETER_ERROR;
291     }
292
293     *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) /
294         (UINT32)cfgQueueInfo[qId].qEntrySizeInWords;
295
296     return IX_SUCCESS;
297 }
298
299 IxQMgrQEntrySizeInWords
300 ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId)
301 {
302     /* No parameter checking as this is used on the data path */
303     return (cfgQueueInfo[qId].qEntrySizeInWords);
304 }
305
306 IX_STATUS
307 ixQMgrWatermarkSet (IxQMgrQId qId,
308                     IxQMgrWMLevel ne,
309                     IxQMgrWMLevel nf)
310 {    
311     IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
312     IxQMgrQStatus qStatusOnExit; /* to this function               */
313
314     if (!ixQMgrQIsConfigured(qId))
315     {
316         return IX_QMGR_Q_NOT_CONFIGURED;
317     }
318
319     if (!watermarkLevelIsOk (qId, ne))
320     {
321         return IX_QMGR_INVALID_Q_WM;
322     }
323
324     if (!watermarkLevelIsOk (qId, nf))
325     {
326         return IX_QMGR_INVALID_Q_WM;
327     }
328
329     /* Get the current queue status */
330     ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
331
332 #ifndef NDEBUG
333     /* Update statistics */
334     stats.wmSetCnt++;
335 #endif
336
337     ixQMgrAqmIfWatermarkSet (qId,
338                             ne,
339                             nf);
340
341     /* Get the current queue status */
342     ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
343   
344     /* If the status has changed return a warning */
345     if (qStatusOnEntry != qStatusOnExit)
346     {
347         return IX_QMGR_WARNING;
348     }
349
350     return IX_SUCCESS;
351 }
352
353 IX_STATUS
354 ixQMgrAvailableSramAddressGet (UINT32 *address,
355                               unsigned *sizeOfFreeRam)
356 {
357     UINT32 aqmLocalBaseAddress;
358
359     if ((NULL == address)||(NULL == sizeOfFreeRam)) 
360     {
361         return IX_QMGR_PARAMETER_ERROR;
362     }
363     if (!cfgInitialized)
364     {
365         return IX_FAIL;
366     }
367
368     *address = freeSramAddress;
369
370     /* Get the virtual SRAM address */
371     ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
372
373     /* 
374      * Calculate the size in bytes of free sram 
375      * i.e. current free SRAM virtual pointer from
376      *      (base + total size)
377      */
378     *sizeOfFreeRam = 
379         (aqmLocalBaseAddress +
380         IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) -
381         freeSramAddress;
382
383     if (0 == *sizeOfFreeRam)
384     {
385         return IX_QMGR_NO_AVAILABLE_SRAM;
386     }
387
388     return IX_SUCCESS;
389 }
390
391 BOOL
392 ixQMgrQIsConfigured (IxQMgrQId qId)
393 {
394     if (!IX_QMGR_QID_IS_VALID(qId))
395     {
396         return false;
397     }
398
399     return cfgQueueInfo[qId].isConfigured;
400 }
401
402 IxQMgrQCfgStats*
403 ixQMgrQCfgStatsGet (void)
404 {
405     return &stats;
406 }
407
408 IxQMgrQCfgStats*
409 ixQMgrQCfgQStatsGet (IxQMgrQId qId)
410 {
411     unsigned int ne;
412     unsigned int nf;
413     UINT32 baseAddress;
414     UINT32 readPtr;
415     UINT32 writePtr;
416
417     stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords;
418     stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords;
419     
420     if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
421     {
422         if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
423         {
424            IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId);
425         }
426     }
427
428     ixQMgrAqmIfQueCfgRead (qId,
429                            stats.qStats[qId].numEntries,
430                            &baseAddress,
431                            &ne,
432                            &nf,
433                            &readPtr,
434                            &writePtr);
435         
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;
441
442     return &stats;
443 }
444
445 /* 
446  * Static function definitions
447  */
448
449 PRIVATE BOOL
450 watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level)
451 {
452     unsigned qSizeInEntries;
453
454     switch (level)
455     {
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:
464             break;
465         default:
466             return false;
467     }
468
469     /* Check watermark is not bigger than the qSizeInEntries */
470     ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries);
471
472     if ((unsigned)level > qSizeInEntries)
473     {
474         return false;
475     }
476
477     return true;
478 }
479
480 PRIVATE BOOL
481 qSizeInWordsIsOk (IxQMgrQSizeInWords qSize)
482 {
483     BOOL status;
484
485     switch (qSize)
486     {   
487         case IX_QMGR_Q_SIZE16:
488         case IX_QMGR_Q_SIZE32:
489         case IX_QMGR_Q_SIZE64:
490         case IX_QMGR_Q_SIZE128:
491             status = true;
492             break;
493         default:
494             status = false;
495             break;
496     }
497
498     return status;
499 }
500
501 PRIVATE BOOL
502 qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize)
503 {
504     BOOL status;
505
506     switch (entrySize)
507     {
508         case IX_QMGR_Q_ENTRY_SIZE1:
509         case IX_QMGR_Q_ENTRY_SIZE2:
510         case IX_QMGR_Q_ENTRY_SIZE4:
511             status = true;
512             break;
513         default:
514             status = false;
515             break;
516     }
517
518     return status;
519 }