/* 
 * @file:    IxQMgrAqmIf.c
 *
 * @author Intel Corporation
 * @date     30-Oct-2001
 *
 * @brief    This component provides a set of functions for
 * perfoming I/O on the AQM hardware.
 * 
 * Design Notes: 
 *              These functions are intended to be as fast as possible
 * and as a result perform NO PARAMETER CHECKING.
 *
 * 
 * @par
 * IXP400 SW Release version 2.0
 * 
 * -- Copyright Notice --
 * 
 * @par
 * Copyright 2001-2005, Intel Corporation.
 * All rights reserved.
 * 
 * @par
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Intel Corporation nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * @par
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * @par
 * -- End of Copyright Notice --
*/

/*
 * Inlines are compiled as function when this is defined.
 * N.B. Must be placed before #include of "IxQMgrAqmIf_p.h
 */
#ifndef IXQMGRAQMIF_P_H
#    define IXQMGRAQMIF_C
#else
#    error
#endif

/*
 * User defined include files.
 */
#include "IxOsal.h"
#include "IxQMgr.h"
#include "IxQMgrAqmIf_p.h"
#include "IxQMgrLog_p.h"


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

/* These defines are the bit offsets of the various fields of
 * the queue configuration register
 */
#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET       0x00
#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET       0x07
#define IX_QMGR_Q_CONFIG_BADDR_OFFSET       0x0E
#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET       0x16
#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET       0x18
#define IX_QMGR_Q_CONFIG_NE_OFFSET          0x1A
#define IX_QMGR_Q_CONFIG_NF_OFFSET          0x1D

#define IX_QMGR_BASE_ADDR_16_WORD_ALIGN     0x40
#define IX_QMGR_BASE_ADDR_16_WORD_SHIFT     0x6

#define IX_QMGR_NE_NF_CLEAR_MASK            0x03FFFFFF
#define IX_QMGR_NE_MASK                     0x7
#define IX_QMGR_NF_MASK                     0x7
#define IX_QMGR_SIZE_MASK                   0x3
#define IX_QMGR_ENTRY_SIZE_MASK             0x3
#define IX_QMGR_BADDR_MASK                  0x003FC000
#define IX_QMGR_RDPTR_MASK                  0x7F
#define IX_QMGR_WRPTR_MASK                  0x7F
#define IX_QMGR_RDWRPTR_MASK                0x00003FFF

#define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000

/* Base address of AQM SRAM */
#define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \
((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE))

/* Min buffer size used for generating buffer size in QUECONFIG */
#define IX_QMGR_MIN_BUFFER_SIZE 16

/* Reset values of QMgr hardware registers */
#define IX_QMGR_QUELOWSTAT_RESET_VALUE    0x33333333
#define IX_QMGR_QUEUOSTAT_RESET_VALUE     0x00000000
#define IX_QMGR_QUEUPPSTAT0_RESET_VALUE   0xFFFFFFFF
#define IX_QMGR_QUEUPPSTAT1_RESET_VALUE   0x00000000
#define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000
#define IX_QMGR_QUEIEREG_RESET_VALUE      0x00000000
#define IX_QMGR_QINTREG_RESET_VALUE       0xFFFFFFFF
#define IX_QMGR_QUECONFIG_RESET_VALUE     0x00000000

#define IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS IX_OSAL_IXP400_QMGR_PHYS_BASE

#define IX_QMGR_QUELOWSTAT_BITS_PER_Q (BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)

#define IX_QMGR_QUELOWSTAT_QID_MASK 0x7
#define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\
        (((qId) * IX_QMGR_NUM_BYTES_PER_WORD) +\
                  IX_QMGR_QUECONFIG_BASE_OFFSET)

#define IX_QMGR_ENTRY1_OFFSET 0
#define IX_QMGR_ENTRY2_OFFSET 1
#define IX_QMGR_ENTRY4_OFFSET 3

/*
 * Variable declarations global to this file. Externs are followed by
 * statics.
 */
UINT32 aqmBaseAddress = 0;
/* Store addresses and bit-masks for certain queue access and status registers.
 * This is to facilitate inlining of QRead, QWrite and QStatusGet functions
 * in IxQMgr,h
 */
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
UINT32 * ixQMgrAqmIfQueAccRegAddr[IX_QMGR_MAX_NUM_QUEUES];
UINT32 ixQMgrAqmIfQueLowStatRegAddr[IX_QMGR_MIN_QUEUPP_QID];
UINT32 ixQMgrAqmIfQueLowStatBitsOffset[IX_QMGR_MIN_QUEUPP_QID];
UINT32 ixQMgrAqmIfQueLowStatBitsMask;
UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
UINT32 ixQMgrAqmIfQueUppStat0BitMask[IX_QMGR_MIN_QUEUPP_QID];
UINT32 ixQMgrAqmIfQueUppStat1BitMask[IX_QMGR_MIN_QUEUPP_QID];

/* 
 * Fast mutexes, one for each queue, used to protect peek & poke functions
 */
IxOsalFastMutex ixQMgrAqmIfPeekPokeFastMutex[IX_QMGR_MAX_NUM_QUEUES];

/*
 * Function prototypes
 */
PRIVATE unsigned
watermarkToAqmWatermark (IxQMgrWMLevel watermark );

PRIVATE unsigned
entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize);

PRIVATE unsigned
bufferSizeToAqmBufferSize (unsigned bufferSizeInWords);

PRIVATE void
ixQMgrAqmIfRegistersReset (void);

PRIVATE void
ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
			    UINT32 configRegWord,
			    unsigned int qEntrySizeInwords,
			    unsigned int qSizeInWords,
			    UINT32 **address);
/*
 * Function definitions
 */
void
ixQMgrAqmIfInit (void)
{
    UINT32 aqmVirtualAddr;
    int i;

    /* The value of aqmBaseAddress depends on the logical address
     * assigned by the MMU.
     */
    aqmVirtualAddr =
	(UINT32) IX_OSAL_MEM_MAP(IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS,
				    IX_OSAL_IXP400_QMGR_MAP_SIZE);
    IX_OSAL_ASSERT (aqmVirtualAddr);
    
    ixQMgrAqmIfBaseAddressSet (aqmVirtualAddr);

    ixQMgrAqmIfRegistersReset ();

    for (i = 0; i< IX_QMGR_MAX_NUM_QUEUES; i++)
    {
	ixOsalFastMutexInit(&ixQMgrAqmIfPeekPokeFastMutex[i]);

	/********************************************************************
	 * Register addresses and bit masks are calculated and stored here to
	 * facilitate inlining of QRead, QWrite and QStatusGet functions in
	 * IxQMgr.h.
	 * These calculations are normally performed dynamically in inlined
	 * functions in IxQMgrAqmIf_p.h, and their semantics are reused here.
	 */

	/* AQM Queue access reg addresses, per queue */
   	ixQMgrAqmIfQueAccRegAddr[i] = 
	    (UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
	ixQMgrQInlinedReadWriteInfo[i].qAccRegAddr = 
	    (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));


	ixQMgrQInlinedReadWriteInfo[i].qConfigRegAddr = 
	    (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(i));

	/* AQM Queue lower-group (0-31), only */
	if (i < IX_QMGR_MIN_QUEUPP_QID)
	{
	    /* AQM Q underflow/overflow status register addresses, per queue */
	    ixQMgrQInlinedReadWriteInfo[i].qUOStatRegAddr = 
		(volatile UINT32 *)(aqmBaseAddress +
		IX_QMGR_QUEUOSTAT0_OFFSET +
		((i / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD) *
		 IX_QMGR_NUM_BYTES_PER_WORD));

	    /* AQM Q underflow status bit masks for status register per queue */
	    ixQMgrQInlinedReadWriteInfo[i].qUflowStatBitMask = 
		(IX_QMGR_UNDERFLOW_BIT_OFFSET + 1) <<
		((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
		 (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));

	    /* AQM Q overflow status bit masks for status register, per queue */
	    ixQMgrQInlinedReadWriteInfo[i].qOflowStatBitMask = 
		(IX_QMGR_OVERFLOW_BIT_OFFSET + 1) <<
		((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
		 (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));

	    /* AQM Q lower-group (0-31) status register addresses, per queue */
	    ixQMgrAqmIfQueLowStatRegAddr[i] = aqmBaseAddress +
		IX_QMGR_QUELOWSTAT0_OFFSET +
		((i / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
		 IX_QMGR_NUM_BYTES_PER_WORD);

	    /* AQM Q lower-group (0-31) status register bit offset */
	    ixQMgrAqmIfQueLowStatBitsOffset[i] =
		(i & (IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD - 1)) * 
		(BITS_PER_WORD / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD);
	}
	else /* AQM Q upper-group (32-63), only */
	{
	    /* AQM Q upper-group (32-63) Nearly Empty status reg bit masks */
	    ixQMgrAqmIfQueUppStat0BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
		(1 << (i - IX_QMGR_MIN_QUEUPP_QID));

	    /* AQM Q upper-group (32-63) Full status register bit masks */
	    ixQMgrAqmIfQueUppStat1BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
		(1 << (i - IX_QMGR_MIN_QUEUPP_QID));
	}
    }

    /* AQM Q lower-group (0-31) status register bit mask */
    ixQMgrAqmIfQueLowStatBitsMask = (1 <<
				    (BITS_PER_WORD /
				     IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)) - 1;

    /* AQM Q upper-group (32-63) Nearly Empty status register address */
    ixQMgrAqmIfQueUppStat0RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET;
    
    /* AQM Q upper-group (32-63) Full status register address */
    ixQMgrAqmIfQueUppStat1RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET;
}

/*
 * Uninitialise the AqmIf module by unmapping memory, etc
 */
void
ixQMgrAqmIfUninit (void)
{
    UINT32 virtAddr;

    ixQMgrAqmIfBaseAddressGet (&virtAddr);
    IX_OSAL_MEM_UNMAP (virtAddr);
    ixQMgrAqmIfBaseAddressSet (0);
}

/*
 * Set the the logical base address of AQM
 */
void
ixQMgrAqmIfBaseAddressSet (UINT32 address)
{
    aqmBaseAddress = address;
}

/*
 * Get the logical base address of AQM
 */
void
ixQMgrAqmIfBaseAddressGet (UINT32 *address)
{
    *address = aqmBaseAddress;
}

/*
 * Get the logical base address of AQM SRAM
 */
void
ixQMgrAqmIfSramBaseAddressGet (UINT32 *address)
{
    *address = aqmBaseAddress                +
	IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET;
}

/*
 * This function will write the status bits of a queue
 * specified by qId.
 */
void
ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId, 
			       UINT32 registerBaseAddrOffset,
			       unsigned queuesPerRegWord,
			       UINT32 value)
{
    volatile UINT32 *registerAddress;
    UINT32 registerWord;
    UINT32 statusBitsMask;
    UINT32 bitsPerQueue;

    bitsPerQueue = BITS_PER_WORD / queuesPerRegWord;

    /*
     * Calculate the registerAddress
     * multiple queues split accross registers
     */
    registerAddress = (UINT32*)(aqmBaseAddress +
				registerBaseAddrOffset +
				((qId / queuesPerRegWord) *
				 IX_QMGR_NUM_BYTES_PER_WORD));    

    /* Read the current data */
    ixQMgrAqmIfWordRead (registerAddress, &registerWord);


    if( (registerBaseAddrOffset == IX_QMGR_INT0SRCSELREG0_OFFSET) &&
        (qId == IX_QMGR_QUEUE_0) )
    {
      statusBitsMask = 0x7 ;   

      /* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3  */
      value &=  0x7 ;        
    }
    else
    {     
      /* Calculate the mask for the status bits for this queue. */
      statusBitsMask = ((1 << bitsPerQueue) - 1);
      statusBitsMask <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);

      /* Mask out bits in value that would overwrite other q data */
      value <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
      value &= statusBitsMask;
    }

    /* Mask out bits to write to */
    registerWord &= ~statusBitsMask;
    

    /* Set the write bits */
    registerWord |= value;

    /*
     * Write the data
     */
    ixQMgrAqmIfWordWrite (registerAddress, registerWord);
}

/*
 * This function generates the parameters that can be used to
 * check if a Qs status matches the specified source select.
 * It calculates which status word to check (statusWordOffset),
 * the value to check the status against (checkValue) and the
 * mask (mask) to mask out all but the bits to check in the status word.
 */
void
ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId,
				 IxQMgrSourceId srcSel,
				 unsigned int *statusWordOffset,
				 UINT32 *checkValue,
				 UINT32 *mask)
{
    UINT32 shiftVal;
   
    if (qId < IX_QMGR_MIN_QUEUPP_QID)
    {
	switch (srcSel)
	{
	    case IX_QMGR_Q_SOURCE_ID_E:
		*checkValue = IX_QMGR_Q_STATUS_E_BIT_MASK;
		*mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
		break;
	    case IX_QMGR_Q_SOURCE_ID_NE:
		*checkValue = IX_QMGR_Q_STATUS_NE_BIT_MASK;
		*mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
		break;
	    case IX_QMGR_Q_SOURCE_ID_NF:
		*checkValue = IX_QMGR_Q_STATUS_NF_BIT_MASK;
		*mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
		break;
	    case IX_QMGR_Q_SOURCE_ID_F:
		*checkValue = IX_QMGR_Q_STATUS_F_BIT_MASK;
		*mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
		break;
	    case IX_QMGR_Q_SOURCE_ID_NOT_E:
		*checkValue = 0;
		*mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
		break;
	    case IX_QMGR_Q_SOURCE_ID_NOT_NE:
		*checkValue = 0;
		*mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
		break;
	    case IX_QMGR_Q_SOURCE_ID_NOT_NF:
		*checkValue = 0;
		*mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
		break;
	    case IX_QMGR_Q_SOURCE_ID_NOT_F:
		*checkValue = 0;
		*mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
		break;
	    default:
		/* Should never hit */
		IX_OSAL_ASSERT(0);
		break;
	}

	/* One nibble of status per queue so need to shift the
	 * check value and mask out to the correct position.
	 */
	shiftVal = (qId % IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) * 
	    IX_QMGR_QUELOWSTAT_BITS_PER_Q;

	/* Calculate the which status word to check from the qId,
	 * 8 Qs status per word
	 */
	*statusWordOffset = qId / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD;

	*checkValue <<= shiftVal;
	*mask <<= shiftVal;
    }
    else
    {
	/* One status word */
	*statusWordOffset = 0;
	/* Single bits per queue and int source bit hardwired  NE,
	 * Qs start at 32.
	 */
	*mask = 1 << (qId - IX_QMGR_MIN_QUEUPP_QID);
	*checkValue = *mask;
    }
}

void
ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId)
{
    volatile UINT32 *registerAddress;
    UINT32 registerWord;
    UINT32 actualBitOffset;
    
    if (qId < IX_QMGR_MIN_QUEUPP_QID)
    {    
	registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
    }
    else
    {
	registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
    }

    actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);

    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
    ixQMgrAqmIfWordWrite (registerAddress, (registerWord | actualBitOffset));
}

void
ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId)
{
    volatile UINT32 *registerAddress;
    UINT32 registerWord;
    UINT32 actualBitOffset;

    if (qId < IX_QMGR_MIN_QUEUPP_QID)
    {    
	registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
    }
    else
    {
	registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
    }

    actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);

    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
    ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset));
}

void
ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId,
		       IxQMgrQSizeInWords qSizeInWords,
		       IxQMgrQEntrySizeInWords entrySizeInWords,
		       UINT32 freeSRAMAddress)
{
    volatile UINT32 *cfgAddress = NULL;
    UINT32 qCfg = 0;
    UINT32 baseAddress = 0;
    unsigned aqmEntrySize = 0;
    unsigned aqmBufferSize = 0;

    /* Build config register */
    aqmEntrySize = entrySizeToAqmEntrySize (entrySizeInWords);
    qCfg |= (aqmEntrySize&IX_QMGR_ENTRY_SIZE_MASK) <<
	IX_QMGR_Q_CONFIG_ESIZE_OFFSET;

    aqmBufferSize = bufferSizeToAqmBufferSize (qSizeInWords);
    qCfg |= (aqmBufferSize&IX_QMGR_SIZE_MASK) << IX_QMGR_Q_CONFIG_BSIZE_OFFSET;

    /* baseAddress, calculated relative to aqmBaseAddress and start address  */
    baseAddress = freeSRAMAddress -
	(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
		   
    /* Verify base address aligned to a 16 word boundary */
    if ((baseAddress % IX_QMGR_BASE_ADDR_16_WORD_ALIGN) != 0)
    {
	IX_QMGR_LOG_ERROR0("ixQMgrAqmIfQueCfgWrite () address is not on 16 word boundary\n");
    }
    /* Now convert it to a 16 word pointer as required by QUECONFIG register */
    baseAddress >>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
    
    
    qCfg |= (baseAddress << IX_QMGR_Q_CONFIG_BADDR_OFFSET);


    cfgAddress = (UINT32*)(aqmBaseAddress +
			IX_QMGR_Q_CONFIG_ADDR_GET(qId));


    /* NOTE: High and Low watermarks are set to zero */
    ixQMgrAqmIfWordWrite (cfgAddress, qCfg);
}

void
ixQMgrAqmIfQueCfgRead (IxQMgrQId qId,
		       unsigned int numEntries,
		       UINT32 *baseAddress,
		       unsigned int *ne,
		       unsigned int *nf,
		       UINT32 *readPtr,
		       UINT32 *writePtr)
{
    UINT32 qcfg;
    UINT32 *cfgAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
    unsigned int qEntrySizeInwords;
    unsigned int qSizeInWords;
    UINT32 *readPtr_ = NULL;
	
    /* Read the queue configuration register */
    ixQMgrAqmIfWordRead (cfgAddress, &qcfg);
    
    /* Extract the base address */
    *baseAddress = (UINT32)((qcfg & IX_QMGR_BADDR_MASK) >>
			    (IX_QMGR_Q_CONFIG_BADDR_OFFSET));

    /* Base address is a 16 word pointer from the start of AQM SRAM.
     * Convert to absolute word address.
     */
    *baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
    *baseAddress += (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET;

    /*
     * Extract the watermarks. 0->0 entries, 1->1 entries, 2->2 entries, 3->4 entries......
     * If ne > 0 ==> neInEntries = 2^(ne - 1)
     * If ne == 0 ==> neInEntries = 0
     * The same applies.
     */
    *ne = ((qcfg) >> (IX_QMGR_Q_CONFIG_NE_OFFSET)) & IX_QMGR_NE_MASK;
    *nf = ((qcfg) >> (IX_QMGR_Q_CONFIG_NF_OFFSET)) & IX_QMGR_NF_MASK;

    if (0 != *ne)
    {
	*ne = 1 << (*ne - 1);	
    }
    if (0 != *nf)
    {
	*nf = 1 << (*nf - 1);
    }

    /* Get the queue entry size in words */
    qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);

    /* Get the queue size in words */
    qSizeInWords = ixQMgrQSizeInWordsGet (qId);

    ixQMgrAqmIfEntryAddressGet (0/* Entry 0. i.e the readPtr*/,
				qcfg,
				qEntrySizeInwords,
				qSizeInWords,
				&readPtr_);
    *readPtr = (UINT32)readPtr_;
    *readPtr -= (UINT32)aqmBaseAddress;/* Offset, not absolute address */

    *writePtr = (qcfg >> IX_QMGR_Q_CONFIG_WRPTR_OFFSET) & IX_QMGR_WRPTR_MASK;
    *writePtr = *baseAddress + (*writePtr * (IX_QMGR_NUM_BYTES_PER_WORD));
    return;
}

unsigned
ixQMgrAqmIfLog2 (unsigned number)
{
    unsigned count = 0;

    /*
     * N.B. this function will return 0
     * for ixQMgrAqmIfLog2 (0)
     */
    while (number/2)
    {
	number /=2;
	count++;	
    }

    return count;
}

void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void)
{

    volatile UINT32 *registerAddress;
    UINT32 registerWord; 

    /*
     * Calculate the registerAddress
     * multiple queues split accross registers
     */
    registerAddress = (UINT32*)(aqmBaseAddress +
				IX_QMGR_INT0SRCSELREG0_OFFSET);    

    /* Read the current data */
    ixQMgrAqmIfWordRead (registerAddress, &registerWord);

    /* Set the write bits */
    registerWord |= (1<<IX_QMGR_INT0SRCSELREG0_BIT3) ;

    /*
     * Write the data
     */
    ixQMgrAqmIfWordWrite (registerAddress, registerWord);
}  


void
ixQMgrAqmIfIntSrcSelWrite (IxQMgrQId qId,
			  IxQMgrSourceId sourceId)
{
    ixQMgrAqmIfQRegisterBitsWrite (qId,
				   IX_QMGR_INT0SRCSELREG0_OFFSET,
				   IX_QMGR_INTSRC_NUM_QUE_PER_WORD,
				   sourceId);
}



void
ixQMgrAqmIfWatermarkSet (IxQMgrQId qId,
			unsigned ne,
			unsigned nf)
{
    volatile UINT32 *address = 0;
    UINT32 value = 0;
    unsigned aqmNeWatermark = 0;
    unsigned aqmNfWatermark = 0;

    address = (UINT32*)(aqmBaseAddress +
		     IX_QMGR_Q_CONFIG_ADDR_GET(qId));

    aqmNeWatermark = watermarkToAqmWatermark (ne);
    aqmNfWatermark = watermarkToAqmWatermark (nf);

    /* Read the current watermarks */
    ixQMgrAqmIfWordRead (address, &value);

    /* Clear out the old watermarks */
    value &=  IX_QMGR_NE_NF_CLEAR_MASK;
    
    /* Generate the value to write */
    value |= (aqmNeWatermark << IX_QMGR_Q_CONFIG_NE_OFFSET) |
	(aqmNfWatermark << IX_QMGR_Q_CONFIG_NF_OFFSET); 

    ixQMgrAqmIfWordWrite (address, value);

}

PRIVATE void
ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
			    UINT32 configRegWord,
			    unsigned int qEntrySizeInwords,
			    unsigned int qSizeInWords,
			    UINT32 **address)
{
    UINT32 readPtr;
    UINT32 baseAddress;
    UINT32 *topOfAqmSram;

    topOfAqmSram = ((UINT32 *)aqmBaseAddress + IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS);

    /* Extract the base address */
    baseAddress = (UINT32)((configRegWord & IX_QMGR_BADDR_MASK) >>
			   (IX_QMGR_Q_CONFIG_BADDR_OFFSET));

    /* Base address is a 16 word pointer from the start of AQM SRAM.
     * Convert to absolute word address.
     */
    baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
    baseAddress += ((UINT32)aqmBaseAddress + (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET);

    /* Extract the read pointer. Read pointer is a word pointer */
    readPtr = (UINT32)((configRegWord >>
			IX_QMGR_Q_CONFIG_RDPTR_OFFSET)&IX_QMGR_RDPTR_MASK);

    /* Read/Write pointers(word pointers)  are offsets from the queue buffer space base address.
     * Calculate the absolute read pointer address. NOTE: Queues are circular buffers.
     */
    readPtr  = (readPtr + (entryIndex * qEntrySizeInwords)) & (qSizeInWords - 1); /* Mask by queue size */
    *address = (UINT32 *)(baseAddress + (readPtr * (IX_QMGR_NUM_BYTES_PER_WORD)));

    switch (qEntrySizeInwords)
    {
	case IX_QMGR_Q_ENTRY_SIZE1:
	    IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY1_OFFSET) < topOfAqmSram);	    
	    break;
	case IX_QMGR_Q_ENTRY_SIZE2:
	    IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY2_OFFSET) < topOfAqmSram);
	    break;
	case IX_QMGR_Q_ENTRY_SIZE4:
	    IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY4_OFFSET) < topOfAqmSram);
	    break;
	default:
	    IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfEntryAddressGet");
	    break;
    }
    
}

IX_STATUS
ixQMgrAqmIfQPeek (IxQMgrQId qId,
		  unsigned int entryIndex,
		  unsigned int *entry)
{
    UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
    UINT32 *entryAddress = NULL;
    UINT32 configRegWordOnEntry;
    UINT32 configRegWordOnExit;
    unsigned int qEntrySizeInwords;
    unsigned int qSizeInWords;

    /* Get the queue entry size in words */
    qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);

    /* Get the queue size in words */
    qSizeInWords = ixQMgrQSizeInWordsGet (qId);

    /* Read the config register */
    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);

    /* Get the entry address */
    ixQMgrAqmIfEntryAddressGet (entryIndex,
				configRegWordOnEntry,
				qEntrySizeInwords,
				qSizeInWords,
				&entryAddress);

    /* Get the lock or return busy */
    if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
    {
	return IX_FAIL;
    }

    while(qEntrySizeInwords--)
    {
	ixQMgrAqmIfWordRead (entryAddress++, entry++);
    }

    /* Release the lock */
    ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);

    /* Read the config register */
    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);

    /* Check that the read and write pointers have not changed */
    if (configRegWordOnEntry != configRegWordOnExit)
    {
	return IX_FAIL;
    }

    return IX_SUCCESS;
}

IX_STATUS
ixQMgrAqmIfQPoke (IxQMgrQId qId,
		  unsigned entryIndex,
		  unsigned int *entry)
{
    UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
    UINT32 *entryAddress = NULL;
    UINT32 configRegWordOnEntry;
    UINT32 configRegWordOnExit;
    unsigned int qEntrySizeInwords;
    unsigned int qSizeInWords;
    
    /* Get the queue entry size in words */
    qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);

    /* Get the queue size in words */
    qSizeInWords = ixQMgrQSizeInWordsGet (qId);

    /* Read the config register */
    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);

    /* Get the entry address */
    ixQMgrAqmIfEntryAddressGet (entryIndex,
				configRegWordOnEntry,
				qEntrySizeInwords,
				qSizeInWords,
				&entryAddress);

    /* Get the lock or return busy */
    if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
    {
	return IX_FAIL;
    }

    /* Else read the entry directly from SRAM. This will not move the read pointer */
    while(qEntrySizeInwords--)
    {
	ixQMgrAqmIfWordWrite (entryAddress++, *entry++);
    }

    /* Release the lock */
    ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);

    /* Read the config register */
    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);

    /* Check that the read and write pointers have not changed */
    if (configRegWordOnEntry != configRegWordOnExit)
    {
	return IX_FAIL;
    }

    return IX_SUCCESS;
}

PRIVATE unsigned
watermarkToAqmWatermark (IxQMgrWMLevel watermark )
{
    unsigned aqmWatermark = 0;

    /*
     * Watermarks 0("000"),1("001"),2("010"),4("011"),
     * 8("100"),16("101"),32("110"),64("111")
     */
    aqmWatermark = ixQMgrAqmIfLog2 (watermark * 2);
    
    return aqmWatermark;
}

PRIVATE unsigned
entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize)
{
    /* entrySize  1("00"),2("01"),4("10") */
    return (ixQMgrAqmIfLog2 (entrySize));
}

PRIVATE unsigned
bufferSizeToAqmBufferSize (unsigned bufferSizeInWords)
{
    /* bufferSize 16("00"),32("01),64("10"),128("11") */
    return (ixQMgrAqmIfLog2 (bufferSizeInWords / IX_QMGR_MIN_BUFFER_SIZE));
}

/*
 * Reset AQM registers to default values.
 */
PRIVATE void
ixQMgrAqmIfRegistersReset (void)
{
    volatile UINT32 *qConfigWordAddress = NULL;
    unsigned int i;

    /*
     * Need to initialize AQM hardware registers to an initial
     * value as init may have been called as a result of a soft
     * reset. i.e. soft reset does not reset hardware registers.
     */

    /* Reset queues 0..31 status registers 0..3 */
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT0_OFFSET), 
			 IX_QMGR_QUELOWSTAT_RESET_VALUE);
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT1_OFFSET), 
			 IX_QMGR_QUELOWSTAT_RESET_VALUE);
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT2_OFFSET), 
			 IX_QMGR_QUELOWSTAT_RESET_VALUE);
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT3_OFFSET), 
			 IX_QMGR_QUELOWSTAT_RESET_VALUE);

    /* Reset underflow/overflow status registers 0..1 */
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT0_OFFSET), 
			 IX_QMGR_QUEUOSTAT_RESET_VALUE);
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT1_OFFSET), 
			 IX_QMGR_QUEUOSTAT_RESET_VALUE);
    
    /* Reset queues 32..63 nearly empty status registers */
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET),
			 IX_QMGR_QUEUPPSTAT0_RESET_VALUE);

    /* Reset queues 32..63 full status registers */
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET),
			 IX_QMGR_QUEUPPSTAT1_RESET_VALUE);

    /* Reset int0 status flag source select registers 0..3 */
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG0_OFFSET),
			 IX_QMGR_INT0SRCSELREG_RESET_VALUE);
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG1_OFFSET),
			 IX_QMGR_INT0SRCSELREG_RESET_VALUE);
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG2_OFFSET),
			 IX_QMGR_INT0SRCSELREG_RESET_VALUE);
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG3_OFFSET),
			 IX_QMGR_INT0SRCSELREG_RESET_VALUE);
	 
    /* Reset queue interrupt enable register 0..1 */
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET),
			 IX_QMGR_QUEIEREG_RESET_VALUE);
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET),
			 IX_QMGR_QUEIEREG_RESET_VALUE);

    /* Reset queue interrupt register 0..1 */
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG0_OFFSET),
			 IX_QMGR_QINTREG_RESET_VALUE);
    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG1_OFFSET),
			 IX_QMGR_QINTREG_RESET_VALUE);

    /* Reset queue configuration words 0..63 */
    qConfigWordAddress = (UINT32 *)(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
    for (i = 0; i < (IX_QMGR_QUECONFIG_SIZE / sizeof(UINT32)); i++)
    {
	ixQMgrAqmIfWordWrite(qConfigWordAddress,
			     IX_QMGR_QUECONFIG_RESET_VALUE);
	/* Next word */
	qConfigWordAddress++;
    }
}

