/**
 * @file    IxQMgrDispatcher.c
 *
 * @author Intel Corporation
 * @date    20-Dec-2001
 *    
 * @brief   This file contains the implementation of the Dispatcher sub component
 *
 * 
 * @par
 * IXP400 SW Release version 2.0
 * 
 * -- Copyright Notice --
 * 
 * @par
 * Copyright 2001-2005, Intel Corporation.
 * All rights reserved.
 * 
 * @par
 * SPDX-License-Identifier:	BSD-3-Clause
 * @par
 * -- End of Copyright Notice --
*/

/*
 * User defined include files.
 */
#include "IxQMgr.h"
#include "IxQMgrAqmIf_p.h"
#include "IxQMgrQCfg_p.h"
#include "IxQMgrDispatcher_p.h"
#include "IxQMgrLog_p.h"
#include "IxQMgrDefines_p.h"
#include "IxFeatureCtrl.h"
#include "IxOsal.h"



/*
 * #defines and macros used in this file.
 */


/*
 * This constant is used to indicate the number of priority levels supported
 */
#define IX_QMGR_NUM_PRIORITY_LEVELS 3

/* 
 * This constant is used to set the size of the array of status words
 */
#define MAX_Q_STATUS_WORDS      4

/*
 * This macro is used to check if a given priority is valid
 */
#define IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority) \
(((priority) >= IX_QMGR_Q_PRIORITY_0) && ((priority) <= IX_QMGR_Q_PRIORITY_2))

/*
 * This macto is used to check that a given interrupt source is valid
 */
#define IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel) \
(((srcSel) >= IX_QMGR_Q_SOURCE_ID_E) && ((srcSel) <= IX_QMGR_Q_SOURCE_ID_NOT_F))

/*
 * Number of times a dummy callback is called before logging a trace
 * message
 */
#define LOG_THROTTLE_COUNT 1000000

/* Priority tables limits */
#define IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX (0)
#define IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX (16)
#define IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX (31)
#define IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX (32)
#define IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX (48)
#define IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX (63)
 
/*
 * This macro is used to check if a given callback type is valid
 */
#define IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type) \
            (((type) >= IX_QMGR_TYPE_REALTIME_OTHER) && \
            ((type) <= IX_QMGR_TYPE_REALTIME_SPORADIC))

/* 
 * define max index in lower queue to use in loops 
 */
#define IX_QMGR_MAX_LOW_QUE_TABLE_INDEX (31)

/*
 * Typedefs whose scope is limited to this file.
 */

/*
 * Information on a queue needed by the Dispatcher
 */
typedef struct 
{
    IxQMgrCallback callback;       /* Notification callback                  */
    IxQMgrCallbackId callbackId;   /* Notification callback identifier       */
    unsigned dummyCallbackCount;   /* Number of times runs of dummy callback */
    IxQMgrPriority priority;       /* Dispatch priority                      */
    unsigned int statusWordOffset; /* Offset to the status word to check     */
    UINT32 statusMask;             /* Status mask                            */    
    UINT32 statusCheckValue;       /* Status check value                     */
    UINT32 intRegCheckMask;	   /* Interrupt register check mask          */
} IxQMgrQInfo;

/*
 * Variable declarations global to this file. Externs are followed by
 * statics.
 */

/* 
 * Flag to keep record of what dispatcher set in featureCtrl when ixQMgrInit()
 * is called. This is needed because it is possible that a client might
 * change whether the live lock prevention dispatcher is used between
 * calls to ixQMgrInit() and ixQMgrDispatcherLoopGet(). 
 */
PRIVATE IX_STATUS ixQMgrOrigB0Dispatcher = IX_FEATURE_CTRL_COMPONENT_ENABLED;

/* 
 * keep record of Q types - not in IxQMgrQInfo for performance as
 * it is only used with ixQMgrDispatcherLoopRunB0LLP()
 */
PRIVATE IxQMgrType ixQMgrQTypes[IX_QMGR_MAX_NUM_QUEUES];

/*
 * This array contains a list of queue identifiers ordered by priority. The table
 * is split logically between queue identifiers 0-31 and 32-63.
 */
static IxQMgrQId priorityTable[IX_QMGR_MAX_NUM_QUEUES];

/*
 * This flag indicates to the dispatcher that the priority table needs to be rebuilt.
 */
static BOOL rebuildTable = false;

/* Dispatcher statistics */
static IxQMgrDispatcherStats dispatcherStats;

/* Table of queue information */
static IxQMgrQInfo dispatchQInfo[IX_QMGR_MAX_NUM_QUEUES];

/* Masks use to identify the first queues in the priority tables 
*  when comparing with the interrupt register
*/
static unsigned int lowPriorityTableFirstHalfMask;
static unsigned int uppPriorityTableFirstHalfMask;

/*
 * Static function prototypes
 */

/*
 * This function is the default callback for all queues
 */
PRIVATE void
dummyCallback (IxQMgrQId qId,	      
	       IxQMgrCallbackId cbId);

PRIVATE void
ixQMgrDispatcherReBuildPriorityTable (void);

/*
 * Function definitions.
 */
void
ixQMgrDispatcherInit (void)
{
    int i;
    IxFeatureCtrlProductId productId = 0;
    IxFeatureCtrlDeviceId deviceId = 0;
    BOOL stickyIntSilicon = true;

    /* Set default priorities */
    for (i=0; i< IX_QMGR_MAX_NUM_QUEUES; i++)
    {
	dispatchQInfo[i].callback = dummyCallback;
	dispatchQInfo[i].callbackId = 0;
	dispatchQInfo[i].dummyCallbackCount = 0;
	dispatchQInfo[i].priority = IX_QMGR_Q_PRIORITY_2;
	dispatchQInfo[i].statusWordOffset = 0;
	dispatchQInfo[i].statusCheckValue = 0;
	dispatchQInfo[i].statusMask = 0;  
        /* 
	 * There are two interrupt registers, 32 bits each. One for the lower
	 * queues(0-31) and one for the upper queues(32-63). Therefore need to
	 * mod by 32 i.e the min upper queue identifier.
	 */
	dispatchQInfo[i].intRegCheckMask = (1<<(i%(IX_QMGR_MIN_QUEUPP_QID)));

        /* 
         * Set the Q types - will only be used with livelock 
         */
        ixQMgrQTypes[i] = IX_QMGR_TYPE_REALTIME_OTHER;

	/* Reset queue statistics */
	dispatcherStats.queueStats[i].callbackCnt = 0;
	dispatcherStats.queueStats[i].priorityChangeCnt = 0;
	dispatcherStats.queueStats[i].intNoCallbackCnt = 0;
	dispatcherStats.queueStats[i].intLostCallbackCnt = 0;
        dispatcherStats.queueStats[i].notificationEnabled = false;
        dispatcherStats.queueStats[i].srcSel = 0;

    }

    /* Priority table. Order the table from queue 0 to 63 */
    ixQMgrDispatcherReBuildPriorityTable();

    /* Reset statistics */
    dispatcherStats.loopRunCnt = 0;

    /* Get the device ID for the underlying silicon */
    deviceId = ixFeatureCtrlDeviceRead();
    
    /* Get the product ID for the underlying silicon */
    productId = ixFeatureCtrlProductIdRead();

    /* 
     * Check featureCtrl to see if Livelock prevention is required 
     */
    ixQMgrOrigB0Dispatcher = ixFeatureCtrlSwConfigurationCheck( 
                                 IX_FEATURECTRL_ORIGB0_DISPATCHER);

    /*
     * Check if the silicon supports the sticky interrupt feature.
     * IF (IXP42X AND A0) -> No sticky interrupt feature supported 
     */
    if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == 
        (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) &&
        (IX_FEATURE_CTRL_SILICON_TYPE_A0 == 
        (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) 
    {
       stickyIntSilicon = false;
    }

    /*
     * IF user wants livelock prev option AND silicon supports sticky interrupt 
     * feature -> enable the sticky interrupt bit
     */
    if ((IX_FEATURE_CTRL_SWCONFIG_DISABLED == ixQMgrOrigB0Dispatcher) &&
         stickyIntSilicon)  
    {
        ixQMgrStickyInterruptRegEnable();
    }
}

IX_STATUS
ixQMgrDispatcherPrioritySet (IxQMgrQId qId,
			     IxQMgrPriority priority)
{   
    int ixQMgrLockKey;

    if (!ixQMgrQIsConfigured(qId))
    {
	return IX_QMGR_Q_NOT_CONFIGURED;
    }
    
    if (!IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority))
    {
	return IX_QMGR_Q_INVALID_PRIORITY;
    }

    ixQMgrLockKey = ixOsalIrqLock();
    
    /* Change priority */
    dispatchQInfo[qId].priority = priority;
    /* Set flag */
    rebuildTable = true;

    ixOsalIrqUnlock(ixQMgrLockKey);

#ifndef NDEBUG
    /* Update statistics */
    dispatcherStats.queueStats[qId].priorityChangeCnt++;
#endif

    return IX_SUCCESS;
}

IX_STATUS
ixQMgrNotificationCallbackSet (IxQMgrQId qId,
			       IxQMgrCallback callback,
			       IxQMgrCallbackId callbackId)
{
    if (!ixQMgrQIsConfigured(qId))
    {
	return IX_QMGR_Q_NOT_CONFIGURED;
    }

    if (NULL == callback)
    {
	/* Reset to dummy callback */
	dispatchQInfo[qId].callback = dummyCallback;
	dispatchQInfo[qId].dummyCallbackCount = 0;
	dispatchQInfo[qId].callbackId = 0;
    }
    else 
    {
	dispatchQInfo[qId].callback = callback;
	dispatchQInfo[qId].callbackId = callbackId;
    }

    return IX_SUCCESS;
}

IX_STATUS
ixQMgrNotificationEnable (IxQMgrQId qId, 
			  IxQMgrSourceId srcSel)
{
    IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
    IxQMgrQStatus qStatusOnExit; /* to this function               */
    int ixQMgrLockKey;

#ifndef NDEBUG
    if (!ixQMgrQIsConfigured (qId))
    {
	return IX_QMGR_Q_NOT_CONFIGURED;
    }

    if ((qId < IX_QMGR_MIN_QUEUPP_QID) &&
       !IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel))
    {
	/* QId 0-31 source id invalid */
	return IX_QMGR_INVALID_INT_SOURCE_ID;
    }

    if ((IX_QMGR_Q_SOURCE_ID_NE != srcSel) &&
	(qId >= IX_QMGR_MIN_QUEUPP_QID))
    {
	/*
	 * For queues 32-63 the interrupt source is fixed to the Nearly
	 * Empty status flag and therefore should have a srcSel of NE.
	 */
	return IX_QMGR_INVALID_INT_SOURCE_ID;
    }
#endif

#ifndef NDEBUG
    dispatcherStats.queueStats[qId].notificationEnabled = true;
    dispatcherStats.queueStats[qId].srcSel = srcSel;
#endif

    /* Get the current queue status */
    ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
  
    /* 
     * Enabling interrupts results in Read-Modify-Write
     * so need critical section
     */

    ixQMgrLockKey = ixOsalIrqLock();

    /* Calculate the checkMask and checkValue for this q */
    ixQMgrAqmIfQStatusCheckValsCalc (qId,
				     srcSel,
				     &dispatchQInfo[qId].statusWordOffset,
				     &dispatchQInfo[qId].statusCheckValue,
				     &dispatchQInfo[qId].statusMask);


    /* Set the interrupt source is this queue is in the range 0-31 */
    if (qId < IX_QMGR_MIN_QUEUPP_QID)
    {
	ixQMgrAqmIfIntSrcSelWrite (qId, srcSel);
    }

    /* Enable the interrupt */
    ixQMgrAqmIfQInterruptEnable (qId);

    ixOsalIrqUnlock(ixQMgrLockKey);
    
    /* Get the current queue status */
    ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
  
    /* If the status has changed return a warning */
    if (qStatusOnEntry != qStatusOnExit)
    {
	return IX_QMGR_WARNING;
    }
    
    return IX_SUCCESS;
}


IX_STATUS
ixQMgrNotificationDisable (IxQMgrQId qId)
{
    int ixQMgrLockKey;

#ifndef NDEBUG
    /* Validate parameters */
    if (!ixQMgrQIsConfigured (qId))
    {
	return IX_QMGR_Q_NOT_CONFIGURED;
    }
#endif
  
    /* 
     * Enabling interrupts results in Read-Modify-Write
     * so need critical section
     */
#ifndef NDEBUG
    dispatcherStats.queueStats[qId].notificationEnabled = false;
#endif

    ixQMgrLockKey = ixOsalIrqLock();

    ixQMgrAqmIfQInterruptDisable (qId);
    
    ixOsalIrqUnlock(ixQMgrLockKey);

    return IX_SUCCESS;    
}

void 
ixQMgrStickyInterruptRegEnable(void)
{
 /* Use Aqm If function to set Interrupt Register0 Bit-3 */ 
 ixQMgrAqmIfIntSrcSelReg0Bit3Set ();   
}

#if !defined __XSCALE__ || defined __linux

/* Count the number of leading zero bits in a word,
 * and return the same value than the CLZ instruction.
 *
 * word (in)    return value (out)
 * 0x80000000   0
 * 0x40000000   1
 * ,,,          ,,,
 * 0x00000002   30
 * 0x00000001   31
 * 0x00000000   32
 *
 * The C version of this function is used as a replacement 
 * for system not providing the equivalent of the CLZ 
 * assembly language instruction.
 *
 * Note that this version is big-endian
 */
unsigned int
ixQMgrCountLeadingZeros(UINT32 word)
{
  unsigned int leadingZerosCount = 0;

  if (word == 0)
  {
      return 32;
  }
  /* search the first bit set by testing the MSB and shifting the input word */
  while ((word & 0x80000000) == 0)
  {
      word <<= 1;
      leadingZerosCount++;
  }
  return leadingZerosCount;
}
#endif /* not  __XSCALE__ or __linux */

void
ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr)
{
  IxFeatureCtrlProductId productId = 0;
  IxFeatureCtrlDeviceId deviceId = 0;
  
  /* Get the device ID for the underlying silicon */
  deviceId = ixFeatureCtrlDeviceRead();

  /* Get the product ID for the underlying silicon */
  productId = ixFeatureCtrlProductIdRead ();

  /* IF (IXP42X AND A0 silicon) -> use ixQMgrDispatcherLoopRunA0 */
  if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X ==
      (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) &&
      (IX_FEATURE_CTRL_SILICON_TYPE_A0 ==  
      (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId)))  
  {
    /*For IXP42X A0 silicon */
    *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunA0 ;
  } 
  else /*For IXP42X B0 or IXP46X silicon*/ 
  { 
    if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixQMgrOrigB0Dispatcher)
    {
        /* Default for IXP42X B0 and IXP46X silicon */
        *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0;
    }
    else 
    {
        /* FeatureCtrl indicated that livelock dispatcher be used */
        *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0LLP;
    }
  }
}

void
ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group)
{
    UINT32 intRegVal;                /* Interrupt reg val */
    UINT32 intRegValAfterWrite;      /* Interrupt reg val after writing back */
    UINT32 intRegCheckMask;          /* Mask for checking interrupt bits */
    UINT32 qStatusWordsB4Write[MAX_Q_STATUS_WORDS];  /* Status b4 interrupt write */
    UINT32 qStatusWordsAfterWrite[MAX_Q_STATUS_WORDS]; /* Status after interrupt write */
    IxQMgrQInfo *currDispatchQInfo;
    BOOL statusChangeFlag;

    int priorityTableIndex;/* Priority table index */
    int qIndex;            /* Current queue being processed */
    int endIndex;          /* Index of last queue to process */

#ifndef NDEBUG
    IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || 
	      (group == IX_QMGR_QUELOW_GROUP));
#endif

    /* Read Q status registers before interrupt status read/write */
    ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsB4Write);

    /* Read the interrupt register */
    ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);

    /* No bit set : nothing to process (the reaminder of the algorithm is
    * based on the fact that the interrupt register value contains at
    * least one bit set
    */
    if (intRegVal == 0) 
    {
#ifndef NDEBUG
	/* Update statistics */
	dispatcherStats.loopRunCnt++;
#endif

	/* Rebuild the priority table if needed */
	if (rebuildTable)
	{
	    ixQMgrDispatcherReBuildPriorityTable ();
	}

	return;
    }
   
    /* Write it back to clear the interrupt */
    ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);

    /* Read Q status registers after interrupt status read/write */
    ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsAfterWrite);
 
    /* get the first queue Id from the interrupt register value */
    qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);

    /* check if any change occured during hw register modifications */ 
    if (IX_QMGR_QUELOW_GROUP == group)
    {
	statusChangeFlag = 
	    (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]) ||
	    (qStatusWordsB4Write[1] != qStatusWordsAfterWrite[1]) ||
	    (qStatusWordsB4Write[2] != qStatusWordsAfterWrite[2]) ||
	    (qStatusWordsB4Write[3] != qStatusWordsAfterWrite[3]);
    }
    else
    {
	statusChangeFlag = 
	    (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]);
	/* Set the queue range based on the queue group to proccess */
	qIndex += IX_QMGR_MIN_QUEUPP_QID;
    }

    if (statusChangeFlag == false)
    {
	/* check if the interrupt register contains 
	 * only 1 bit set (happy day scenario)
	 */
	currDispatchQInfo = &dispatchQInfo[qIndex];
	if (intRegVal == currDispatchQInfo->intRegCheckMask)
	{
	    /* only 1 queue event triggered a notification *
	     * Call the callback function for this queue 
	     */
	    currDispatchQInfo->callback (qIndex,
					 currDispatchQInfo->callbackId);  
#ifndef NDEBUG
	    /* Update statistics */
	    dispatcherStats.queueStats[qIndex].callbackCnt++;
#endif
	}
	else 
	{
	    /* the event is triggered by more than 1 queue, 
	     * the queue search will be starting from the beginning
	     * or the middle of the priority table
	     *
	     * the serach will end when all the bits of the interrupt
	     * register are cleared. There is no need to maintain
	     * a seperate value and test it at each iteration.
	     */
	    if (IX_QMGR_QUELOW_GROUP == group)
	    {
		/* check if any bit related to queues in the first
		 * half of the priority table is set
		 */
		if (intRegVal & lowPriorityTableFirstHalfMask)
		{
		    priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
		}
		else
		{
		    priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;
		}
	    }
	    else 
	    {
		/* check if any bit related to queues in the first
		 * half of the priority table is set
		 */
		if (intRegVal & uppPriorityTableFirstHalfMask)
		{
		    priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
		}
		else
		{
		    priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;
		}
	    }
	    
	    /* iterate following the priority table until all the bits 
	     * of the interrupt register are cleared.
	     */
	    do
	    {
		qIndex = priorityTable[priorityTableIndex++];
		currDispatchQInfo = &dispatchQInfo[qIndex];
		intRegCheckMask = currDispatchQInfo->intRegCheckMask;
		
		/* If this queue caused this interrupt to be raised */
		if (intRegVal & intRegCheckMask)
		{
		    /* Call the callback function for this queue */
		    currDispatchQInfo->callback (qIndex,
						 currDispatchQInfo->callbackId);
#ifndef NDEBUG
		    /* Update statistics */
		    dispatcherStats.queueStats[qIndex].callbackCnt++;
#endif
		    
		    /* Clear the interrupt register bit */
		    intRegVal &= ~intRegCheckMask;
		}
	    }
	    while(intRegVal);
	}
    }
    else
    {
    /* A change in queue status occured during the hw interrupt
     * register update. To maintain the interrupt consistency, it
     * is necessary to iterate through all queues of the queue group.
     */

    /* Read interrupt status again */
    ixQMgrAqmIfQInterruptRegRead (group, &intRegValAfterWrite);

    if (IX_QMGR_QUELOW_GROUP == group)
    {
	priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
	endIndex = IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX;
    }
    else
    {
	priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
	endIndex = IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX;
    }

    for ( ; priorityTableIndex<=endIndex; priorityTableIndex++)
    {
	qIndex = priorityTable[priorityTableIndex];
	currDispatchQInfo = &dispatchQInfo[qIndex];
	intRegCheckMask = currDispatchQInfo->intRegCheckMask;

	/* If this queue caused this interrupt to be raised */
	if (intRegVal & intRegCheckMask)
	{  
	    /* Call the callback function for this queue */
	    currDispatchQInfo->callback (qIndex,
					 currDispatchQInfo->callbackId);
#ifndef NDEBUG
	    /* Update statistics */
	    dispatcherStats.queueStats[qIndex].callbackCnt++;
#endif
	    
	} /* if (intRegVal .. */

	/* 
	 * If interrupt bit is set in intRegValAfterWrite don't
	 * proceed as this will be caught in next interrupt
	 */
	else if ((intRegValAfterWrite & intRegCheckMask) == 0)
	{
	    /* Check if an interrupt was lost for this Q */
	    if (ixQMgrAqmIfQStatusCheck(qStatusWordsB4Write,
					qStatusWordsAfterWrite,
					currDispatchQInfo->statusWordOffset,
					currDispatchQInfo->statusCheckValue,
					currDispatchQInfo->statusMask))
	    {
		/* Call the callback function for this queue */
		currDispatchQInfo->callback (qIndex, 
					     dispatchQInfo[qIndex].callbackId);                 
#ifndef NDEBUG
		/* Update statistics */
		dispatcherStats.queueStats[qIndex].callbackCnt++;
		dispatcherStats.queueStats[qIndex].intLostCallbackCnt++;
#endif
	    } /* if ixQMgrAqmIfQStatusCheck(.. */
	} /* else if ((intRegValAfterWrite ... */
    } /* for (priorityTableIndex=0 ... */
    }

    /* Rebuild the priority table if needed */
    if (rebuildTable)
    {
	ixQMgrDispatcherReBuildPriorityTable ();
    }

#ifndef NDEBUG
    /* Update statistics */
    dispatcherStats.loopRunCnt++;
#endif
}



void
ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group)
{
    UINT32 intRegVal;                /* Interrupt reg val */
    UINT32 intRegCheckMask;          /* Mask for checking interrupt bits */
    IxQMgrQInfo *currDispatchQInfo;


    int priorityTableIndex; /* Priority table index */
    int qIndex;             /* Current queue being processed */

#ifndef NDEBUG
    IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) ||
              (group == IX_QMGR_QUELOW_GROUP));
    IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || 
	      (group == IX_QMGR_QUELOW_GROUP));
#endif

    /* Read the interrupt register */
    ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);


    /* No queue has interrupt register set */
    if (intRegVal != 0)
    {

            /* Write it back to clear the interrupt */
            ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);

            /* get the first queue Id from the interrupt register value */
            qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);

            if (IX_QMGR_QUEUPP_GROUP == group)
            {
                /* Set the queue range based on the queue group to proccess */
                qIndex += IX_QMGR_MIN_QUEUPP_QID;
            }

            /* check if the interrupt register contains
             * only 1 bit set
             * For example:
             *                                        intRegVal = 0x0010
             *               currDispatchQInfo->intRegCheckMask = 0x0010
             *    intRegVal == currDispatchQInfo->intRegCheckMask is true.
             */
             currDispatchQInfo = &dispatchQInfo[qIndex];
             if (intRegVal == currDispatchQInfo->intRegCheckMask)
             {
                /* only 1 queue event triggered a notification *
                 * Call the callback function for this queue
                 */
                currDispatchQInfo->callback (qIndex,
                                     currDispatchQInfo->callbackId);
#ifndef NDEBUG
                /* Update statistics */
                dispatcherStats.queueStats[qIndex].callbackCnt++;
#endif
             }
             else
             {
                 /* the event is triggered by more than 1 queue,
                  * the queue search will be starting from the beginning
                  * or the middle of the priority table
                  *
                  * the serach will end when all the bits of the interrupt
                  * register are cleared. There is no need to maintain
                  * a seperate value and test it at each iteration.
                  */
                 if (IX_QMGR_QUELOW_GROUP == group)
                 {
                     /* check if any bit related to queues in the first
                      * half of the priority table is set
                      */
                     if (intRegVal & lowPriorityTableFirstHalfMask)
                     {
                         priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
                     }
                     else
                     {
                         priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;
                     }
                 }
                else
                 {
                     /* check if any bit related to queues in the first
                      * half of the priority table is set
                      */
                     if (intRegVal & uppPriorityTableFirstHalfMask)
                     {
                         priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
                     }
                     else
                     {
                         priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;
                     }
                 }

                 /* iterate following the priority table until all the bits
                  * of the interrupt register are cleared.
                  */
                 do
                 {
                     qIndex = priorityTable[priorityTableIndex++];
                     currDispatchQInfo = &dispatchQInfo[qIndex];
                     intRegCheckMask = currDispatchQInfo->intRegCheckMask;

                     /* If this queue caused this interrupt to be raised */
                     if (intRegVal & intRegCheckMask)
                     {
                         /* Call the callback function for this queue */
                         currDispatchQInfo->callback (qIndex,
                                              currDispatchQInfo->callbackId);
#ifndef NDEBUG
                         /* Update statistics */
                         dispatcherStats.queueStats[qIndex].callbackCnt++;
#endif

                         /* Clear the interrupt register bit */
                         intRegVal &= ~intRegCheckMask;
                     }
                  }
                  while(intRegVal);
             } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */
     } /* End of intRegVal != 0 */

#ifndef NDEBUG
    /* Update statistics */
    dispatcherStats.loopRunCnt++;
#endif

    /* Rebuild the priority table if needed */
    if (rebuildTable)
    {
        ixQMgrDispatcherReBuildPriorityTable ();
    }
}

void
ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group)
{
    UINT32 intRegVal =0;                /* Interrupt reg val */
    UINT32 intRegCheckMask;          /* Mask for checking interrupt bits */
    IxQMgrQInfo *currDispatchQInfo;

    int priorityTableIndex; /* Priority table index */
    int qIndex;             /* Current queue being processed */

    UINT32 intRegValCopy = 0;
    UINT32 intEnableRegVal = 0;
    UINT8 i = 0;

#ifndef NDEBUG
    IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) ||
              (group == IX_QMGR_QUELOW_GROUP));
#endif

    /* Read the interrupt register */
    ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);

    /* 
     * mask any interrupts that are not enabled 
     */
    ixQMgrAqmIfQInterruptEnableRegRead (group, &intEnableRegVal);
    intRegVal &= intEnableRegVal;

    /* No queue has interrupt register set */
    if (intRegVal != 0)
    {
        if (IX_QMGR_QUELOW_GROUP == group)
        {
            /*
             * As the sticky bit is set, the interrupt register will 
             * not clear if write back at this point because the condition
             * has not been cleared. Take a copy and write back later after
             * the condition has been cleared
             */
            intRegValCopy = intRegVal;
        }
        else
        {
            /* no sticky for upper Q's, so write back now */
            ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);
        }

        /* get the first queue Id from the interrupt register value */
        qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);

        if (IX_QMGR_QUEUPP_GROUP == group)
        {
            /* Set the queue range based on the queue group to proccess */
            qIndex += IX_QMGR_MIN_QUEUPP_QID;
        }

        /* check if the interrupt register contains
        * only 1 bit set
        * For example:
        *                                        intRegVal = 0x0010
        *               currDispatchQInfo->intRegCheckMask = 0x0010
        *    intRegVal == currDispatchQInfo->intRegCheckMask is true.
        */
        currDispatchQInfo = &dispatchQInfo[qIndex];
        if (intRegVal == currDispatchQInfo->intRegCheckMask)
        {

            /* 
             * check if Q type periodic -  only lower queues can
             * have there type set to periodic 
             */
            if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex])
            {
                /* 
                 * Disable the notifications on any sporadics 
                 */
                for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
                {
                    if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i])
                    {
                        ixQMgrNotificationDisable(i);
#ifndef NDEBUG
                        /* Update statistics */
                        dispatcherStats.queueStats[i].disableCount++;
#endif
                    }
                }
            }

            currDispatchQInfo->callback (qIndex,
                                         currDispatchQInfo->callbackId);
#ifndef NDEBUG
            /* Update statistics */
            dispatcherStats.queueStats[qIndex].callbackCnt++;
#endif
        }
        else
        {
            /* the event is triggered by more than 1 queue,
            * the queue search will be starting from the beginning
            * or the middle of the priority table
            *
            * the serach will end when all the bits of the interrupt
            * register are cleared. There is no need to maintain
            * a seperate value and test it at each iteration.
            */
            if (IX_QMGR_QUELOW_GROUP == group)
            {
                /* check if any bit related to queues in the first
                 * half of the priority table is set
                 */
                if (intRegVal & lowPriorityTableFirstHalfMask)
                {
                    priorityTableIndex =
                                       IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
                }
                else
                {
                    priorityTableIndex =
                                       IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;
                }
            }
            else
            {
                /* check if any bit related to queues in the first
                 * half of the priority table is set
                 */
                if (intRegVal & uppPriorityTableFirstHalfMask)
                {
                    priorityTableIndex =
                                       IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
                }
                else
                {
                    priorityTableIndex =
                                       IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;
                }
            }

            /* iterate following the priority table until all the bits
             * of the interrupt register are cleared.
             */
            do
            {
                qIndex = priorityTable[priorityTableIndex++];
                currDispatchQInfo = &dispatchQInfo[qIndex];
                intRegCheckMask = currDispatchQInfo->intRegCheckMask;

                /* If this queue caused this interrupt to be raised */
                if (intRegVal & intRegCheckMask)
                {
                    /* 
                     * check if Q type periodic - only lower queues can
                     * have there type set to periodic. There can only be one
                     * periodic queue, so the sporadics are only disabled once.
                     */
                    if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex])
                    {
                        /* 
                         * Disable the notifications on any sporadics 
                         */
                        for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
                        {
                            if (IX_QMGR_TYPE_REALTIME_SPORADIC == 
                                    ixQMgrQTypes[i])
                            {
                                ixQMgrNotificationDisable(i);
                                /* 
                                 * remove from intRegVal as we don't want 
                                 * to service any sporadics now
                                 */
                                intRegVal &= ~dispatchQInfo[i].intRegCheckMask;
#ifndef NDEBUG
                                /* Update statistics */
                                dispatcherStats.queueStats[i].disableCount++;
#endif
                            }
                        }
                    }

                    currDispatchQInfo->callback (qIndex,
                                                 currDispatchQInfo->callbackId);
#ifndef NDEBUG
                    /* Update statistics */
                    dispatcherStats.queueStats[qIndex].callbackCnt++;
#endif
                    /* Clear the interrupt register bit */
                    intRegVal &= ~intRegCheckMask;
                }
            }
            while(intRegVal);
        } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */
    } /* End of intRegVal != 0 */

#ifndef NDEBUG
    /* Update statistics */
    dispatcherStats.loopRunCnt++;
#endif

    if ((intRegValCopy != 0) && (IX_QMGR_QUELOW_GROUP == group))
    {
        /* 
         * lower groups (therefore sticky) AND at least one enabled interrupt
         * Write back to clear the interrupt 
         */
        ixQMgrAqmIfQInterruptRegWrite (IX_QMGR_QUELOW_GROUP, intRegValCopy);
    }

    /* Rebuild the priority table if needed */
    if (rebuildTable)
    {
        ixQMgrDispatcherReBuildPriorityTable ();
    }
}

PRIVATE void
ixQMgrDispatcherReBuildPriorityTable (void)
{
    UINT32 qIndex;
    UINT32 priority;
    int lowQuePriorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
    int uppQuePriorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;

    /* Reset the rebuild flag */
    rebuildTable = false;

    /* initialize the mak used to identify the queues in the first half
     * of the priority table
     */
    lowPriorityTableFirstHalfMask = 0;
    uppPriorityTableFirstHalfMask = 0;
    
    /* For each priority level */
    for(priority=0; priority<IX_QMGR_NUM_PRIORITY_LEVELS; priority++)
    {
	/* Foreach low queue in this priority */
	for(qIndex=0; qIndex<IX_QMGR_MIN_QUEUPP_QID; qIndex++)
	{
	    if (dispatchQInfo[qIndex].priority == priority)
	    { 
		/* build the priority table bitmask which match the
		 * queues of the first half of the priority table 
		 */
		if (lowQuePriorityTableIndex < IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX) 
		{
		    lowPriorityTableFirstHalfMask |= dispatchQInfo[qIndex].intRegCheckMask;
		}
		/* build the priority table */
		priorityTable[lowQuePriorityTableIndex++] = qIndex;
	    }
	}
	/* Foreach upp queue */
	for(qIndex=IX_QMGR_MIN_QUEUPP_QID; qIndex<=IX_QMGR_MAX_QID; qIndex++)
	{
	    if (dispatchQInfo[qIndex].priority == priority)
	    {
		/* build the priority table bitmask which match the
		 * queues of the first half of the priority table 
		 */
		if (uppQuePriorityTableIndex < IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX) 
		{
		    uppPriorityTableFirstHalfMask |= dispatchQInfo[qIndex].intRegCheckMask;
		}
		/* build the priority table */
		priorityTable[uppQuePriorityTableIndex++] = qIndex;
	    }
	}
    }
}

IxQMgrDispatcherStats*
ixQMgrDispatcherStatsGet (void)
{
    return &dispatcherStats;
}

PRIVATE void
dummyCallback (IxQMgrQId qId,
	       IxQMgrCallbackId cbId)
{
    /* Throttle the trace message */
    if ((dispatchQInfo[qId].dummyCallbackCount % LOG_THROTTLE_COUNT) == 0)
    {
	IX_QMGR_LOG_WARNING2("--> dummyCallback: qId (%d), callbackId (%d)\n",qId,cbId);
    }
    dispatchQInfo[qId].dummyCallbackCount++;

#ifndef NDEBUG
    /* Update statistcs */
    dispatcherStats.queueStats[qId].intNoCallbackCnt++;
#endif
}
void
ixQMgrLLPShow (int resetStats)
{
#ifndef NDEBUG
    UINT8 i = 0;
    UINT32 intEnableRegVal = 0;

    printf ("Livelock statistics are printed on the fly.\n");
    printf ("qId Type     EnableCnt DisableCnt IntEnableState Callbacks\n");
    printf ("=== ======== ========= ========== ============== =========\n");

    for (i=0; i<= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
    {
        if (ixQMgrQTypes[i] != IX_QMGR_TYPE_REALTIME_OTHER)
        {
            printf (" %2d ", i);

            if (ixQMgrQTypes[i] == IX_QMGR_TYPE_REALTIME_SPORADIC)
            {
                printf ("Sporadic");
            }
            else
            {
                printf ("Periodic");
            }

           
            ixQMgrAqmIfQInterruptEnableRegRead (IX_QMGR_QUELOW_GROUP, 
                                                    &intEnableRegVal);
            	

	    intEnableRegVal &= dispatchQInfo[i].intRegCheckMask;
            intEnableRegVal = intEnableRegVal >> i;

            printf (" %10d %10d %10d %10d\n",
                    dispatcherStats.queueStats[i].enableCount,
                    dispatcherStats.queueStats[i].disableCount,
                    intEnableRegVal,
                    dispatcherStats.queueStats[i].callbackCnt);

            if (resetStats)
            {
                dispatcherStats.queueStats[i].enableCount =
                dispatcherStats.queueStats[i].disableCount = 
                dispatcherStats.queueStats[i].callbackCnt = 0;
            }
        }
    }
#else
    IX_QMGR_LOG0("Livelock Prevention statistics are only collected in debug mode\n");
#endif
}

void
ixQMgrPeriodicDone (void)
{
    UINT32 i = 0;
    UINT32 ixQMgrLockKey = 0;

    /* 
     * for the lower queues
     */
    for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
    {
        /*
         * check for sporadics 
         */
        if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i])
        {
             /* 
              * enable any sporadics 
              */
             ixQMgrLockKey = ixOsalIrqLock();
             ixQMgrAqmIfQInterruptEnable(i);
             ixOsalIrqUnlock(ixQMgrLockKey);
#ifndef NDEBUG
             /* 
              * Update statistics 
              */
             dispatcherStats.queueStats[i].enableCount++;
             dispatcherStats.queueStats[i].notificationEnabled = true;
#endif
        }
    }
}
IX_STATUS
ixQMgrCallbackTypeSet (IxQMgrQId qId, 
                       IxQMgrType type)
{
    UINT32 ixQMgrLockKey = 0;
    IxQMgrType ixQMgrOldType =0;

#ifndef NDEBUG
    if (!ixQMgrQIsConfigured(qId))
    {
        return IX_QMGR_Q_NOT_CONFIGURED;
    }
    if (qId >= IX_QMGR_MIN_QUEUPP_QID)
    {
        return IX_QMGR_PARAMETER_ERROR;
    }
    if(!IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type))
    {
        return IX_QMGR_PARAMETER_ERROR;
    }
#endif

    ixQMgrOldType = ixQMgrQTypes[qId];
    ixQMgrQTypes[qId] = type;

    /*
     * check if Q has been changed from type SPORADIC
     */
    if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrOldType)
    {
       /* 
        * previously Q was a SPORADIC, this means that LLP
        * might have had it disabled. enable it now.
        */
       ixQMgrLockKey = ixOsalIrqLock();
       ixQMgrAqmIfQInterruptEnable(qId);
       ixOsalIrqUnlock(ixQMgrLockKey);

#ifndef NDEBUG
       /* 
        * Update statistics 
        */
       dispatcherStats.queueStats[qId].enableCount++;
#endif
    }

    return IX_SUCCESS;
}

IX_STATUS
ixQMgrCallbackTypeGet (IxQMgrQId qId, 
                       IxQMgrType *type)
{
#ifndef NDEBUG
    if (!ixQMgrQIsConfigured(qId))
    {
        return IX_QMGR_Q_NOT_CONFIGURED;
    }
    if (qId >= IX_QMGR_MIN_QUEUPP_QID)
    {
        return IX_QMGR_PARAMETER_ERROR;
    }
    if(type == NULL)
    {
         return IX_QMGR_PARAMETER_ERROR;
    }
#endif

    *type = ixQMgrQTypes[qId];
    return IX_SUCCESS;
}
