]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/npe/IxNpeMhConfig.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / net / npe / IxNpeMhConfig.c
1 /**
2  * @file IxNpeMhConfig.c
3  *
4  * @author Intel Corporation
5  * @date 18 Jan 2002
6  *
7  * @brief This file contains the implementation of the private API for the
8  * Configuration module.
9  *
10  * 
11  * @par
12  * IXP400 SW Release version 2.0
13  * 
14  * -- Copyright Notice --
15  * 
16  * @par
17  * Copyright 2001-2005, Intel Corporation.
18  * All rights reserved.
19  * 
20  * @par
21  * SPDX-License-Identifier:     BSD-3-Clause
22  * @par
23  * -- End of Copyright Notice --
24 */
25
26 /*
27  * Put the system defined include files required.
28  */
29
30
31 /*
32  * Put the user defined include files required.
33  */
34
35 #include "IxOsal.h"
36
37 #include "IxNpeMhMacros_p.h"
38
39 #include "IxNpeMhConfig_p.h"
40
41 /*
42  * #defines and macros used in this file.
43  */
44 #define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
45                                               * retries before
46                                               * timeout
47                                                                   */  
48
49 /*
50  * Typedefs whose scope is limited to this file.
51  */
52
53 /**
54  * @struct IxNpeMhConfigStats
55  *
56  * @brief This structure is used to maintain statistics for the
57  * Configuration module.
58  */
59
60 typedef struct
61 {
62     UINT32 outFifoReads;        /**< outFifo reads */
63     UINT32 inFifoWrites;        /**< inFifo writes */
64     UINT32 maxInFifoFullRetries;   /**< max retries if inFIFO full   */
65     UINT32 maxOutFifoEmptyRetries; /**< max retries if outFIFO empty */
66 } IxNpeMhConfigStats;
67
68 /*
69  * Variable declarations global to this file only.  Externs are followed by
70  * static variables.
71  */
72
73 IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] =
74 {
75     {
76         0,
77         IX_NPEMH_NPEA_INT,
78         0,
79         0,
80         0,
81         0,
82         0,
83         NULL,
84         false
85     },
86     {
87         0,
88         IX_NPEMH_NPEB_INT,
89         0,
90         0,
91         0,
92         0,
93         0,
94         NULL,
95         false
96     },
97     {
98         0,
99         IX_NPEMH_NPEC_INT,
100         0,
101         0,
102         0,
103         0,
104         0,
105         NULL,
106         false
107     }
108 };
109
110 PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES];
111
112 /*
113  * Extern function prototypes.
114  */
115
116 /*
117  * Static function prototypes.
118  */
119 PRIVATE
120 void ixNpeMhConfigIsr (void *parameter);
121
122 /*
123  * Function definition: ixNpeMhConfigIsr
124  */
125
126 PRIVATE
127 void ixNpeMhConfigIsr (void *parameter)
128 {
129     IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter;
130     UINT32 ofint;
131     volatile UINT32 *statusReg =
132         (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
133
134     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
135                      "ixNpeMhConfigIsr\n");
136
137     /* get the OFINT (OutFifo interrupt) bit of the status register */
138     IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT);
139
140     /* if the OFINT status bit is set */
141     if (ofint)
142     {
143         /* if there is an ISR registered for this NPE */
144         if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
145         {
146             /* invoke the ISR routine */
147             ixNpeMhConfigNpeInfo[npeId].isr (npeId);
148         }
149         else
150         {
151             /* if we don't service the interrupt the NPE will continue */
152             /* to trigger the interrupt indefinitely */
153             IX_NPEMH_ERROR_REPORT ("No ISR registered to service "
154                                    "interrupt\n");
155         }
156     }
157
158     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
159                      "ixNpeMhConfigIsr\n");
160 }
161
162 /*
163  * Function definition: ixNpeMhConfigInitialize
164  */
165
166 void ixNpeMhConfigInitialize (
167     IxNpeMhNpeInterrupts npeInterrupts)
168 {
169     IxNpeMhNpeId npeId;
170     UINT32 virtualAddr[IX_NPEMH_NUM_NPES];
171
172     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
173                      "ixNpeMhConfigInitialize\n");
174
175     /* Request a mapping for the NPE-A config register address space */
176     virtualAddr[IX_NPEMH_NPEID_NPEA] =
177         (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEA_BASE,
178                                      IX_OSAL_IXP400_NPEA_MAP_SIZE);
179     IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEA]);
180
181     /* Request a mapping for the NPE-B config register address space */
182     virtualAddr[IX_NPEMH_NPEID_NPEB] =
183         (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEB_BASE,
184                                      IX_OSAL_IXP400_NPEB_MAP_SIZE);
185     IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEB]);
186     
187     /* Request a mapping for the NPE-C config register address space */
188     virtualAddr[IX_NPEMH_NPEID_NPEC] =
189         (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEC_BASE,
190                                      IX_OSAL_IXP400_NPEC_MAP_SIZE);
191     IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEC]);
192
193     /* for each NPE ... */
194     for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
195     {
196         /* declare a convenience pointer */
197         IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
198         
199         /* store the virtual addresses of the NPE registers for later use */
200         npeInfo->virtualRegisterBase  = virtualAddr[npeId];
201         npeInfo->statusRegister  = virtualAddr[npeId] + IX_NPEMH_NPESTAT_OFFSET;
202         npeInfo->controlRegister = virtualAddr[npeId] + IX_NPEMH_NPECTL_OFFSET;
203         npeInfo->inFifoRegister  = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
204         npeInfo->outFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
205
206         /* for test purposes - to verify the register addresses */
207         IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d status register  = "
208                          "0x%08X\n", npeId, npeInfo->statusRegister);
209         IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d control register = "
210                          "0x%08X\n", npeId, npeInfo->controlRegister);
211         IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d inFifo register  = "
212                          "0x%08X\n", npeId, npeInfo->inFifoRegister);
213         IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d outFifo register = "
214                          "0x%08X\n", npeId, npeInfo->outFifoRegister);
215
216         /* connect our ISR to the NPE interrupt */
217         (void) ixOsalIrqBind (
218             npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId);
219
220         /* initialise a mutex for this NPE */
221         (void) ixOsalMutexInit (&npeInfo->mutex);
222
223         /* if we should service the NPE's "outFIFO not empty" interrupt */
224         if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES)
225         {
226             /* enable the NPE's "outFIFO not empty" interrupt */
227             ixNpeMhConfigNpeInterruptEnable (npeId);
228         }
229         else
230         {
231             /* disable the NPE's "outFIFO not empty" interrupt */
232             ixNpeMhConfigNpeInterruptDisable (npeId);
233         }
234     }
235
236     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
237                      "ixNpeMhConfigInitialize\n");
238 }
239
240 /*
241  * Function definition: ixNpeMhConfigUninit
242  */
243
244 void ixNpeMhConfigUninit (void)
245 {
246     IxNpeMhNpeId npeId;
247
248     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
249                      "ixNpeMhConfigUninit\n");
250
251     /* for each NPE ... */
252     for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
253     {
254         /* declare a convenience pointer */
255         IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
256         
257         /* disconnect ISR */
258         ixOsalIrqUnbind(npeInfo->interruptId);
259
260         /* destroy mutex associated with this NPE */
261         ixOsalMutexDestroy(&npeInfo->mutex);
262         
263         IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase);
264
265         npeInfo->virtualRegisterBase  = 0;
266         npeInfo->statusRegister  = 0;
267         npeInfo->controlRegister = 0;
268         npeInfo->inFifoRegister  = 0;
269         npeInfo->outFifoRegister = 0;
270     }
271
272     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
273                      "ixNpeMhConfigUninit\n");
274 }
275
276 /*
277  * Function definition: ixNpeMhConfigIsrRegister
278  */
279
280 void ixNpeMhConfigIsrRegister (
281     IxNpeMhNpeId npeId,
282     IxNpeMhConfigIsr isr)
283 {
284     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
285                      "ixNpeMhConfigIsrRegister\n");
286
287     /* check if there is already an ISR registered for this NPE */
288     if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
289     {
290         IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n");
291     }
292
293     /* save the ISR routine with the NPE info */
294     ixNpeMhConfigNpeInfo[npeId].isr = isr;
295
296     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
297                      "ixNpeMhConfigIsrRegister\n");
298 }
299
300 /*
301  * Function definition: ixNpeMhConfigNpeInterruptEnable
302  */
303
304 BOOL ixNpeMhConfigNpeInterruptEnable (
305     IxNpeMhNpeId npeId)
306 {
307     UINT32 ofe;
308     volatile UINT32 *controlReg =
309         (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
310
311     /* get the OFE (OutFifoEnable) bit of the control register */
312     IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
313
314     /* if the interrupt is disabled then we must enable it */
315     if (!ofe)
316     {
317         /* set the OFE (OutFifoEnable) bit of the control register */
318         /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
319         /* time for the write to have effect */
320         IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
321                                       (IX_NPEMH_NPE_CTL_OFE |
322                                        IX_NPEMH_NPE_CTL_OFEWE),
323                                       (IX_NPEMH_NPE_CTL_OFE |
324                                        IX_NPEMH_NPE_CTL_OFEWE));
325     }
326
327     /* return the previous state of the interrupt */
328     return (ofe != 0);
329 }
330
331 /*
332  * Function definition: ixNpeMhConfigNpeInterruptDisable
333  */
334
335 BOOL ixNpeMhConfigNpeInterruptDisable (
336     IxNpeMhNpeId npeId)
337 {
338     UINT32 ofe;
339     volatile UINT32 *controlReg =
340         (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
341
342     /* get the OFE (OutFifoEnable) bit of the control register */
343     IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
344
345     /* if the interrupt is enabled then we must disable it */
346     if (ofe)
347     {
348         /* unset the OFE (OutFifoEnable) bit of the control register */
349         /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
350         /* time for the write to have effect */
351         IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
352                                       (0                    |
353                                        IX_NPEMH_NPE_CTL_OFEWE),
354                                       (IX_NPEMH_NPE_CTL_OFE |
355                                        IX_NPEMH_NPE_CTL_OFEWE));
356     }
357
358     /* return the previous state of the interrupt */
359     return (ofe != 0);
360 }
361
362 /*
363  * Function definition: ixNpeMhConfigMessageIdGet
364  */
365
366 IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
367     IxNpeMhMessage message)
368 {
369     /* return the most-significant byte of the first word of the */
370     /* message */
371     return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF));
372 }
373
374 /*
375  * Function definition: ixNpeMhConfigNpeIdIsValid
376  */
377
378 BOOL ixNpeMhConfigNpeIdIsValid (
379     IxNpeMhNpeId npeId)
380 {
381     /* check that the npeId parameter is within the range of valid IDs */
382     return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES);
383 }
384
385 /*
386  * Function definition: ixNpeMhConfigLockGet
387  */
388
389 void ixNpeMhConfigLockGet (
390     IxNpeMhNpeId npeId)
391 {
392     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
393                      "ixNpeMhConfigLockGet\n");
394
395     /* lock the mutex for this NPE */
396     (void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex, 
397                             IX_OSAL_WAIT_FOREVER);
398
399     /* disable the NPE's "outFIFO not empty" interrupt */
400     ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
401         ixNpeMhConfigNpeInterruptDisable (npeId);
402
403     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
404                      "ixNpeMhConfigLockGet\n");
405 }
406
407 /*
408  * Function definition: ixNpeMhConfigLockRelease
409  */
410
411 void ixNpeMhConfigLockRelease (
412     IxNpeMhNpeId npeId)
413 {
414     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
415                      "ixNpeMhConfigLockRelease\n");
416
417     /* if the interrupt was previously enabled */
418     if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState)
419     {
420         /* enable the NPE's "outFIFO not empty" interrupt */
421         ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
422             ixNpeMhConfigNpeInterruptEnable (npeId);
423     }
424
425     /* unlock the mutex for this NPE */
426     (void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex);
427
428     IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
429                      "ixNpeMhConfigLockRelease\n");
430 }
431
432 /*
433  * Function definition: ixNpeMhConfigInFifoWrite
434  */
435
436 IX_STATUS ixNpeMhConfigInFifoWrite (
437     IxNpeMhNpeId npeId,
438     IxNpeMhMessage message)
439 {
440     volatile UINT32 *npeInFifo =
441         (UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister;
442     UINT32 retriesCount = 0;
443
444     /* write the first word of the message to the NPE's inFIFO */
445     IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]);
446
447     /* need to wait for room to write second word - see SCR #493,
448        poll for maximum number of retries, if exceed maximum
449        retries, exit from while loop */
450     while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
451         && ixNpeMhConfigInFifoIsFull (npeId))
452     {
453         retriesCount++;
454     }
455
456     /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
457     if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
458     {
459         return IX_NPEMH_CRITICAL_NPE_ERR;   
460     }    
461     
462     /* write the second word of the message to the NPE's inFIFO */
463     IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]);
464
465     /* record in the stats the maximum number of retries needed */
466     if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount)
467     {
468         ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount;
469     }
470
471     /* update statistical info */
472     ixNpeMhConfigStats[npeId].inFifoWrites++;
473     
474     return IX_SUCCESS;
475 }
476
477 /*
478  * Function definition: ixNpeMhConfigOutFifoRead
479  */
480
481 IX_STATUS ixNpeMhConfigOutFifoRead (
482     IxNpeMhNpeId npeId,
483     IxNpeMhMessage *message)
484 {
485     volatile UINT32 *npeOutFifo =
486         (UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister;
487     UINT32 retriesCount = 0;
488
489     /* read the first word of the message from the NPE's outFIFO */
490     IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]);
491
492     /* need to wait for NPE to write second word - see SCR #493 
493        poll for maximum number of retries, if exceed maximum
494        retries, exit from while loop */
495     while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
496         && ixNpeMhConfigOutFifoIsEmpty (npeId))
497     {
498         retriesCount++;
499     }
500
501     /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
502     if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
503     {
504         return IX_NPEMH_CRITICAL_NPE_ERR;   
505     } 
506     
507     /* read the second word of the message from the NPE's outFIFO */
508     IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]);
509
510     /* record in the stats the maximum number of retries needed */
511     if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount)
512     {
513         ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount;
514     }
515
516     /* update statistical info */
517     ixNpeMhConfigStats[npeId].outFifoReads++;
518     
519     return IX_SUCCESS;
520 }
521
522 /*
523  * Function definition: ixNpeMhConfigShow
524  */
525
526 void ixNpeMhConfigShow (
527     IxNpeMhNpeId npeId)
528 {
529     /* show the message fifo read counter */
530     IX_NPEMH_SHOW ("Message FIFO reads",
531                    ixNpeMhConfigStats[npeId].outFifoReads);
532
533     /* show the message fifo write counter */
534     IX_NPEMH_SHOW ("Message FIFO writes",
535                    ixNpeMhConfigStats[npeId].inFifoWrites);
536
537     /* show the max retries performed when inFIFO full */
538     IX_NPEMH_SHOW ("Max inFIFO Full retries",
539                    ixNpeMhConfigStats[npeId].maxInFifoFullRetries);
540
541     /* show the max retries performed when outFIFO empty */
542     IX_NPEMH_SHOW ("Max outFIFO Empty retries",
543                    ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries);
544
545     /* show the current status of the inFifo */
546     ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
547                "InFifo is %s and %s\n",
548                (ixNpeMhConfigInFifoIsEmpty (npeId) ? 
549                 (int) "EMPTY" : (int) "NOT EMPTY"),
550                (ixNpeMhConfigInFifoIsFull (npeId) ? 
551                 (int) "FULL" : (int) "NOT FULL"),
552                0, 0, 0, 0);
553
554     /* show the current status of the outFifo */
555     ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
556                "OutFifo is %s and %s\n",
557                (ixNpeMhConfigOutFifoIsEmpty (npeId) ? 
558                 (int) "EMPTY" : (int) "NOT EMPTY"),
559                (ixNpeMhConfigOutFifoIsFull (npeId) ? 
560                 (int) "FULL" : (int) "NOT FULL"),
561                0, 0, 0, 0);
562 }
563
564 /*
565  * Function definition: ixNpeMhConfigShowReset
566  */
567
568 void ixNpeMhConfigShowReset (
569     IxNpeMhNpeId npeId)
570 {
571     /* reset the message fifo read counter */
572     ixNpeMhConfigStats[npeId].outFifoReads = 0;
573
574     /* reset the message fifo write counter */
575     ixNpeMhConfigStats[npeId].inFifoWrites = 0;
576
577     /* reset the max inFIFO Full retries counter */
578     ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0;
579
580     /* reset the max outFIFO empty retries counter */
581     ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0;
582 }
583
584