2 * @file IxNpeMhConfig.c
4 * @author Intel Corporation
7 * @brief This file contains the implementation of the private API for the
8 * Configuration module.
12 * IXP400 SW Release version 2.0
14 * -- Copyright Notice --
17 * Copyright 2001-2005, Intel Corporation.
18 * All rights reserved.
21 * SPDX-License-Identifier: BSD-3-Clause
23 * -- End of Copyright Notice --
27 * Put the system defined include files required.
32 * Put the user defined include files required.
37 #include "IxNpeMhMacros_p.h"
39 #include "IxNpeMhConfig_p.h"
42 * #defines and macros used in this file.
44 #define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
50 * Typedefs whose scope is limited to this file.
54 * @struct IxNpeMhConfigStats
56 * @brief This structure is used to maintain statistics for the
57 * Configuration module.
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 */
69 * Variable declarations global to this file only. Externs are followed by
73 IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] =
110 PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES];
113 * Extern function prototypes.
117 * Static function prototypes.
120 void ixNpeMhConfigIsr (void *parameter);
123 * Function definition: ixNpeMhConfigIsr
127 void ixNpeMhConfigIsr (void *parameter)
129 IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter;
131 volatile UINT32 *statusReg =
132 (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
134 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
135 "ixNpeMhConfigIsr\n");
137 /* get the OFINT (OutFifo interrupt) bit of the status register */
138 IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT);
140 /* if the OFINT status bit is set */
143 /* if there is an ISR registered for this NPE */
144 if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
146 /* invoke the ISR routine */
147 ixNpeMhConfigNpeInfo[npeId].isr (npeId);
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 "
158 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
159 "ixNpeMhConfigIsr\n");
163 * Function definition: ixNpeMhConfigInitialize
166 void ixNpeMhConfigInitialize (
167 IxNpeMhNpeInterrupts npeInterrupts)
170 UINT32 virtualAddr[IX_NPEMH_NUM_NPES];
172 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
173 "ixNpeMhConfigInitialize\n");
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]);
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]);
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]);
193 /* for each NPE ... */
194 for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
196 /* declare a convenience pointer */
197 IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
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;
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);
216 /* connect our ISR to the NPE interrupt */
217 (void) ixOsalIrqBind (
218 npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId);
220 /* initialise a mutex for this NPE */
221 (void) ixOsalMutexInit (&npeInfo->mutex);
223 /* if we should service the NPE's "outFIFO not empty" interrupt */
224 if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES)
226 /* enable the NPE's "outFIFO not empty" interrupt */
227 ixNpeMhConfigNpeInterruptEnable (npeId);
231 /* disable the NPE's "outFIFO not empty" interrupt */
232 ixNpeMhConfigNpeInterruptDisable (npeId);
236 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
237 "ixNpeMhConfigInitialize\n");
241 * Function definition: ixNpeMhConfigUninit
244 void ixNpeMhConfigUninit (void)
248 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
249 "ixNpeMhConfigUninit\n");
251 /* for each NPE ... */
252 for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
254 /* declare a convenience pointer */
255 IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
258 ixOsalIrqUnbind(npeInfo->interruptId);
260 /* destroy mutex associated with this NPE */
261 ixOsalMutexDestroy(&npeInfo->mutex);
263 IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase);
265 npeInfo->virtualRegisterBase = 0;
266 npeInfo->statusRegister = 0;
267 npeInfo->controlRegister = 0;
268 npeInfo->inFifoRegister = 0;
269 npeInfo->outFifoRegister = 0;
272 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
273 "ixNpeMhConfigUninit\n");
277 * Function definition: ixNpeMhConfigIsrRegister
280 void ixNpeMhConfigIsrRegister (
282 IxNpeMhConfigIsr isr)
284 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
285 "ixNpeMhConfigIsrRegister\n");
287 /* check if there is already an ISR registered for this NPE */
288 if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
290 IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n");
293 /* save the ISR routine with the NPE info */
294 ixNpeMhConfigNpeInfo[npeId].isr = isr;
296 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
297 "ixNpeMhConfigIsrRegister\n");
301 * Function definition: ixNpeMhConfigNpeInterruptEnable
304 BOOL ixNpeMhConfigNpeInterruptEnable (
308 volatile UINT32 *controlReg =
309 (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
311 /* get the OFE (OutFifoEnable) bit of the control register */
312 IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
314 /* if the interrupt is disabled then we must enable it */
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));
327 /* return the previous state of the interrupt */
332 * Function definition: ixNpeMhConfigNpeInterruptDisable
335 BOOL ixNpeMhConfigNpeInterruptDisable (
339 volatile UINT32 *controlReg =
340 (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
342 /* get the OFE (OutFifoEnable) bit of the control register */
343 IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
345 /* if the interrupt is enabled then we must disable it */
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,
353 IX_NPEMH_NPE_CTL_OFEWE),
354 (IX_NPEMH_NPE_CTL_OFE |
355 IX_NPEMH_NPE_CTL_OFEWE));
358 /* return the previous state of the interrupt */
363 * Function definition: ixNpeMhConfigMessageIdGet
366 IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
367 IxNpeMhMessage message)
369 /* return the most-significant byte of the first word of the */
371 return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF));
375 * Function definition: ixNpeMhConfigNpeIdIsValid
378 BOOL ixNpeMhConfigNpeIdIsValid (
381 /* check that the npeId parameter is within the range of valid IDs */
382 return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES);
386 * Function definition: ixNpeMhConfigLockGet
389 void ixNpeMhConfigLockGet (
392 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
393 "ixNpeMhConfigLockGet\n");
395 /* lock the mutex for this NPE */
396 (void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex,
397 IX_OSAL_WAIT_FOREVER);
399 /* disable the NPE's "outFIFO not empty" interrupt */
400 ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
401 ixNpeMhConfigNpeInterruptDisable (npeId);
403 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
404 "ixNpeMhConfigLockGet\n");
408 * Function definition: ixNpeMhConfigLockRelease
411 void ixNpeMhConfigLockRelease (
414 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
415 "ixNpeMhConfigLockRelease\n");
417 /* if the interrupt was previously enabled */
418 if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState)
420 /* enable the NPE's "outFIFO not empty" interrupt */
421 ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
422 ixNpeMhConfigNpeInterruptEnable (npeId);
425 /* unlock the mutex for this NPE */
426 (void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex);
428 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
429 "ixNpeMhConfigLockRelease\n");
433 * Function definition: ixNpeMhConfigInFifoWrite
436 IX_STATUS ixNpeMhConfigInFifoWrite (
438 IxNpeMhMessage message)
440 volatile UINT32 *npeInFifo =
441 (UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister;
442 UINT32 retriesCount = 0;
444 /* write the first word of the message to the NPE's inFIFO */
445 IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]);
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))
456 /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
457 if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
459 return IX_NPEMH_CRITICAL_NPE_ERR;
462 /* write the second word of the message to the NPE's inFIFO */
463 IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]);
465 /* record in the stats the maximum number of retries needed */
466 if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount)
468 ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount;
471 /* update statistical info */
472 ixNpeMhConfigStats[npeId].inFifoWrites++;
478 * Function definition: ixNpeMhConfigOutFifoRead
481 IX_STATUS ixNpeMhConfigOutFifoRead (
483 IxNpeMhMessage *message)
485 volatile UINT32 *npeOutFifo =
486 (UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister;
487 UINT32 retriesCount = 0;
489 /* read the first word of the message from the NPE's outFIFO */
490 IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]);
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))
501 /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
502 if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
504 return IX_NPEMH_CRITICAL_NPE_ERR;
507 /* read the second word of the message from the NPE's outFIFO */
508 IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]);
510 /* record in the stats the maximum number of retries needed */
511 if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount)
513 ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount;
516 /* update statistical info */
517 ixNpeMhConfigStats[npeId].outFifoReads++;
523 * Function definition: ixNpeMhConfigShow
526 void ixNpeMhConfigShow (
529 /* show the message fifo read counter */
530 IX_NPEMH_SHOW ("Message FIFO reads",
531 ixNpeMhConfigStats[npeId].outFifoReads);
533 /* show the message fifo write counter */
534 IX_NPEMH_SHOW ("Message FIFO writes",
535 ixNpeMhConfigStats[npeId].inFifoWrites);
537 /* show the max retries performed when inFIFO full */
538 IX_NPEMH_SHOW ("Max inFIFO Full retries",
539 ixNpeMhConfigStats[npeId].maxInFifoFullRetries);
541 /* show the max retries performed when outFIFO empty */
542 IX_NPEMH_SHOW ("Max outFIFO Empty retries",
543 ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries);
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"),
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"),
565 * Function definition: ixNpeMhConfigShowReset
568 void ixNpeMhConfigShowReset (
571 /* reset the message fifo read counter */
572 ixNpeMhConfigStats[npeId].outFifoReads = 0;
574 /* reset the message fifo write counter */
575 ixNpeMhConfigStats[npeId].inFifoWrites = 0;
577 /* reset the max inFIFO Full retries counter */
578 ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0;
580 /* reset the max outFIFO empty retries counter */
581 ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0;