/**
 * @file IxEthDataPlane.c
 *
 * @author Intel Corporation
 * @date 12-Feb-2002
 *
 * @brief This file contains the implementation of the IXPxxx
 * Ethernet Access Data plane component
 *
 * Design Notes:
 *
 * @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 --
 */

#include "IxNpeMh.h"
#include "IxEthAcc.h"
#include "IxEthDB.h"
#include "IxOsal.h"
#include "IxEthDBPortDefs.h"
#include "IxFeatureCtrl.h"
#include "IxEthAcc_p.h"
#include "IxEthAccQueueAssign_p.h"

extern PUBLIC IxEthAccMacState ixEthAccMacState[];
extern PUBLIC UINT32 ixEthAccNewSrcMask;

/**
 * private functions prototype
 */
PRIVATE IX_OSAL_MBUF *
ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask);

PRIVATE UINT32
ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf);

PRIVATE UINT32
ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf);

PRIVATE IxEthAccStatus
ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId,
				IxEthAccTxPriority *priorityPtr);

PRIVATE IxEthAccStatus
ixEthAccTxFromSwQ(IxEthAccPortId portId,
		  IxEthAccTxPriority priority);

PRIVATE IxEthAccStatus
ixEthAccRxFreeFromSwQ(IxEthAccPortId portId);

PRIVATE void
ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf);

PRIVATE void
ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf);

PRIVATE IX_STATUS
ixEthAccQmgrLockTxWrite(IxEthAccPortId portId,
			UINT32 qBuffer);

PRIVATE IX_STATUS
ixEthAccQmgrLockRxWrite(IxEthAccPortId portId,
			UINT32 qBuffer);

PRIVATE IX_STATUS
ixEthAccQmgrTxWrite(IxEthAccPortId portId,
		    UINT32 qBuffer,
		    UINT32 priority);

/**
 * @addtogroup IxEthAccPri
 *@{
 */

/* increment a counter only when stats are enabled */
#define TX_STATS_INC(port,field) \
        IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccTxData.stats.field)
#define RX_STATS_INC(port,field) \
        IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccRxData.stats.field)

/* always increment the counter (mainly used for unexpected errors) */
#define TX_INC(port,field) \
        ixEthAccPortData[port].ixEthAccTxData.stats.field++
#define RX_INC(port,field) \
        ixEthAccPortData[port].ixEthAccRxData.stats.field++

PRIVATE IxEthAccDataPlaneStats     ixEthAccDataStats;

extern IxEthAccPortDataInfo   ixEthAccPortData[];
extern IxEthAccInfo   ixEthAccDataInfo;

PRIVATE IxOsalFastMutex txWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS];
PRIVATE IxOsalFastMutex rxWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS];

/**
 *
 * @brief Mbuf header conversion macros : they implement the
 *  different conversions using a temporary value. They also double-check
 *  that the parameters can be converted to/from NPE format.
 *
 */
#if defined(__wince) && !defined(IN_KERNEL)
#define PTR_VIRT2NPE(ptrSrc,dst) \
  do { UINT32 temp; \
      IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \
      IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \
      temp = (UINT32)IX_OSAL_MBUF_MBUF_VIRTUAL_TO_PHYSICAL_TRANSLATION((IX_OSAL_MBUF*)ptrSrc); \
      (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \
  while(0)

#define PTR_NPE2VIRT(type,src,ptrDst) \
  do { void *temp; \
      IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \
      IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \
      IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \
      temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \
      (ptrDst) = (type)IX_OSAL_MBUF_MBUF_PHYSICAL_TO_VIRTUAL_TRANSLATION(temp); } \
  while(0)
#else
#define PTR_VIRT2NPE(ptrSrc,dst) \
  do { UINT32 temp; \
      IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \
      IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \
      temp = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(ptrSrc); \
      (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \
  while(0)

#define PTR_NPE2VIRT(type,src,ptrDst) \
  do { void *temp; \
      IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \
      IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \
      IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \
      temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \
      (ptrDst) = (type)IX_OSAL_MMU_PHYS_TO_VIRT(temp); } \
  while(0)
#endif

/**
 *
 * @brief Mbuf payload pointer conversion macros : Wince has its own
 *  method to convert the buffer pointers
 */
#if defined(__wince) && !defined(IN_KERNEL)
#define DATAPTR_VIRT2NPE(ptrSrc,dst) \
  do { UINT32 temp; \
      temp = (UINT32)IX_OSAL_MBUF_DATA_VIRTUAL_TO_PHYSICAL_TRANSLATION(ptrSrc); \
      (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \
  while(0)

#else
#define DATAPTR_VIRT2NPE(ptrSrc,dst) PTR_VIRT2NPE(IX_OSAL_MBUF_MDATA(ptrSrc),dst)
#endif


/* Flush the shared part of the mbuf header */
#define IX_ETHACC_NE_CACHE_FLUSH(mbufPtr) \
  do { \
      IX_OSAL_CACHE_FLUSH(IX_ETHACC_NE_SHARED(mbufPtr), \
			      sizeof(IxEthAccNe)); \
    } \
  while(0)

/* Invalidate the shared part of the mbuf header */
#define IX_ETHACC_NE_CACHE_INVALIDATE(mbufPtr) \
  do { \
      IX_OSAL_CACHE_INVALIDATE(IX_ETHACC_NE_SHARED(mbufPtr), \
				   sizeof(IxEthAccNe)); \
    } \
  while(0)

/* Preload one cache line (shared mbuf headers are aligned
 * and their size is 1 cache line)
 *
 * IX_OSAL_CACHED  is defined when the mbuf headers are
 * allocated from cached memory.
 *
 * Other processor on emulation environment may not implement
 * preload function
 */
#ifdef IX_OSAL_CACHED
	#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince)
		#define IX_ACC_DATA_CACHE_PRELOAD(ptr) \
		do { /* preload a cache line (Xscale Processor) */ \
			__asm__ (" pld [%0]\n": : "r" (ptr)); \
		} \
		while(0)
	#else
		/* preload not implemented on different processor */
		#define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \
		do { /* nothing */ } while (0)
	#endif
#else
	/* preload not needed if cache is not enabled */
	#define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \
	do { /* nothing */ } while (0)
#endif

/**
 *
 * @brief function to retrieve the correct pointer from
 * a queue entry posted by the NPE
 *
 * @param qEntry : entry from qmgr queue
 *        mask : applicable mask for this queue
 *        (4 most significant bits are used for additional informations)
 *
 * @return IX_OSAL_MBUF * pointer to mbuf header
 *
 * @internal
 */
PRIVATE IX_OSAL_MBUF *
ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask)
{
    IX_OSAL_MBUF *mbufPtr;

    if (qEntry != 0)
    {
        /* mask NPE bits (e.g. priority, port ...) */
        qEntry &= mask;

#if IX_ACC_DRAM_PHYS_OFFSET != 0
        /* restore the original address pointer (if PHYS_OFFSET is not 0) */
        qEntry |= (IX_ACC_DRAM_PHYS_OFFSET & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
#endif
        /* get the mbuf pointer address from the npe-shared address */
        qEntry -= offsetof(IX_OSAL_MBUF,ix_ne);

        /* phys2virt mbuf */
        mbufPtr = (IX_OSAL_MBUF *)IX_OSAL_MMU_PHYS_TO_VIRT(qEntry);

        /* preload the cacheline shared with NPE */
        IX_ACC_DATA_CACHE_PRELOAD(IX_ETHACC_NE_SHARED(mbufPtr));

        /* preload the cacheline used by xscale */
        IX_ACC_DATA_CACHE_PRELOAD(mbufPtr);
    }
    else
    {
	mbufPtr = NULL;
    }

    return mbufPtr;
}

/* Convert the mbuf header for NPE transmission */
PRIVATE UINT32
ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf)
{
    UINT32 qbuf;
    UINT32 len;

    /* endianess swap for tci and flags
       note: this is done only once, even for chained buffers */
    IX_ETHACC_NE_FLAGS(mbuf)   = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf));
    IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf));

    /* test for unchained mbufs */
    if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL)
    {
	/* "best case" scenario : unchained mbufs */
	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxMBufs);

	/* payload pointer conversion */
	DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf));

	/* unchained mbufs : the frame length is the mbuf length
	 * and the 2 identical lengths are stored in the same
	 * word.
	 */
	len = IX_OSAL_MBUF_MLEN(mbuf);

	/* set the length in both length and pktLen 16-bits fields */
	len |= (len << IX_ETHNPE_ACC_LENGTH_OFFSET);
	IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len);

	/* unchained mbufs : next contains 0 */
	IX_ETHACC_NE_NEXT(mbuf) = 0;

	/* flush shared header after all address conversions */
	IX_ETHACC_NE_CACHE_FLUSH(mbuf);
    }
    else
    {
	/* chained mbufs */
	IX_OSAL_MBUF *ptr = mbuf;
	IX_OSAL_MBUF *nextPtr;
	UINT32 frmLen;

	/* get the frame length from the header of the first buffer */
	frmLen = IX_OSAL_MBUF_PKT_LEN(mbuf);

	do
	{
	    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxMBufs);

	    /* payload pointer */
	    DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr));
	    /* Buffer length and frame length are stored in the same word */
	    len = IX_OSAL_MBUF_MLEN(ptr);
	    len = frmLen | (len << IX_ETHNPE_ACC_LENGTH_OFFSET);
	    IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len);

	    /* get the virtual next chain pointer */
	    nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr);
	    if (nextPtr != NULL)
	    {
		/* shared pointer of the next buffer is chained */
		PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr),
			     IX_ETHACC_NE_NEXT(ptr));
	    }
	    else
	    {
		IX_ETHACC_NE_NEXT(ptr) = 0;
	    }

	    /* flush shared header after all address conversions */
	    IX_ETHACC_NE_CACHE_FLUSH(ptr);

	    /* move to next buffer */
	    ptr = nextPtr;

	    /* the frame length field is set only in the first buffer
	     * and is zeroed in the next buffers
	     */
	    frmLen = 0;
	}
	while(ptr != NULL);

    }

    /* virt2phys mbuf itself */
    qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(
		  IX_ETHACC_NE_SHARED(mbuf));

    /* Ensure the bits which are reserved to exchange information with
     * the NPE are cleared
     *
     * If the mbuf address is not correctly aligned, or from an
     * incompatible memory range, there is no point to continue
     */
    IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) == 0),
	      "Invalid address range");

    return qbuf;
}

/* Convert the mbuf header for NPE reception */
PRIVATE UINT32
ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf)
{
    UINT32 len;
    UINT32 qbuf;

    if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL)
    {
	/* "best case" scenario : unchained mbufs */
	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxFreeMBufs);

	/* unchained mbufs : payload pointer */
	DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf));

	/* unchained mbufs : set the buffer length
	* and the frame length field is zeroed
	*/
	len = (IX_OSAL_MBUF_MLEN(mbuf) << IX_ETHNPE_ACC_LENGTH_OFFSET);
	IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len);

	/* unchained mbufs : next pointer is null */
	IX_ETHACC_NE_NEXT(mbuf) = 0;

	/* flush shared header after all address conversions */
	IX_ETHACC_NE_CACHE_FLUSH(mbuf);

	/* remove shared header cache line */
	IX_ETHACC_NE_CACHE_INVALIDATE(mbuf);
    }
    else
    {
	/* chained mbufs */
	IX_OSAL_MBUF *ptr = mbuf;
	IX_OSAL_MBUF *nextPtr;

	do
	{
	    /* chained mbufs */
	    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxFreeMBufs);

	    /* we must save virtual next chain pointer */
	    nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr);

	    if (nextPtr != NULL)
	    {
		/* chaining pointer for NPE */
		PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr),
			     IX_ETHACC_NE_NEXT(ptr));
	    }
	    else
	    {
		IX_ETHACC_NE_NEXT(ptr) = 0;
	    }

	    /* payload pointer */
	    DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr));

	    /* buffer length */
	    len = (IX_OSAL_MBUF_MLEN(ptr) << IX_ETHNPE_ACC_LENGTH_OFFSET);
	    IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len);

	    /* flush shared header after all address conversions */
	    IX_ETHACC_NE_CACHE_FLUSH(ptr);

	    /* remove shared header cache line */
	    IX_ETHACC_NE_CACHE_INVALIDATE(ptr);

	    /* next mbuf in the chain */
	    ptr = nextPtr;
	}
	while(ptr != NULL);
    }

    /* virt2phys mbuf itself */
    qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(
		  IX_ETHACC_NE_SHARED(mbuf));

    /* Ensure the bits which are reserved to exchange information with
     * the NPE are cleared
     *
     * If the mbuf address is not correctly aligned, or from an
     * incompatible memory range, there is no point to continue
     */
    IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) == 0),
	      "Invalid address range");

    return qbuf;
}

/* Convert the mbuf header after NPE transmission
 * Since there is nothing changed by the NPE, there is no need
 * to process anything but the update of internal stats
 * when they are enabled
*/
PRIVATE void
ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf)
{
#ifndef NDEBUG
    /* test for unchained mbufs */
    if (IX_ETHACC_NE_NEXT(mbuf) == 0)
    {
	/* unchained mbufs : update the stats */
	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxDoneMBufs);
    }
    else
    {
	/* chained mbufs : walk the chain and update the stats */
	IX_OSAL_MBUF *ptr = mbuf;

	do
	{
	    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxDoneMBufs);
	    ptr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr);
	}
	while (ptr != NULL);
    }
#endif
}

/* Convert the mbuf header after NPE reception */
PRIVATE void
ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf)
{
    UINT32 len;

    /* endianess swap for tci and flags
       note: this is done only once, even for chained buffers */
    IX_ETHACC_NE_FLAGS(mbuf)   = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf));
    IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf));

    /* test for unchained mbufs */
    if (IX_ETHACC_NE_NEXT(mbuf) == 0)
    {
	/* unchained mbufs */
	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxMBufs);

	/* get the frame length. it is the same than the buffer length */
	len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf));
	len &= IX_ETHNPE_ACC_PKTLENGTH_MASK;
	IX_OSAL_MBUF_PKT_LEN(mbuf) = IX_OSAL_MBUF_MLEN(mbuf) = len;

        /* clears the next packet field */
	IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) = NULL;
    }
    else
    {
	IX_OSAL_MBUF *ptr = mbuf;
	IX_OSAL_MBUF *nextPtr;
	UINT32 frmLen;

	/* convert the frame length */
	frmLen = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf));
	IX_OSAL_MBUF_PKT_LEN(mbuf) = (frmLen & IX_ETHNPE_ACC_PKTLENGTH_MASK);

        /* chained mbufs */
	do
	{
	    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxMBufs);

	    /* convert the length */
	    len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(ptr));
	    IX_OSAL_MBUF_MLEN(ptr) = (len >> IX_ETHNPE_ACC_LENGTH_OFFSET);

            /* get the next pointer */
	    PTR_NPE2VIRT(IX_OSAL_MBUF *,IX_ETHACC_NE_NEXT(ptr), nextPtr);
	    if (nextPtr != NULL)
	    {
		nextPtr = (IX_OSAL_MBUF *)((UINT8 *)nextPtr - offsetof(IX_OSAL_MBUF,ix_ne));
	    }
	    /* set the next pointer */
	    IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr) = nextPtr;

	    /* move to the next buffer */
	    ptr = nextPtr;
	}
	while (ptr != NULL);
    }
}

/* write to qmgr if possible and report an overflow if not possible
 * Use a fast lock to protect the queue write.
 * This way, the tx feature is reentrant.
 */
PRIVATE IX_STATUS
ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, UINT32 qBuffer)
{
    IX_STATUS qStatus;
    if (ixOsalFastMutexTryLock(&txWriteMutex[portId]) == IX_SUCCESS)
    {
	qStatus = ixQMgrQWrite(
	       IX_ETH_ACC_PORT_TO_TX_Q_ID(portId),
	       &qBuffer);
#ifndef NDEBUG
	if (qStatus != IX_SUCCESS)
	{
	    TX_STATS_INC(portId, txOverflow);
	}
#endif
	ixOsalFastMutexUnlock(&txWriteMutex[portId]);
    }
    else
    {
	TX_STATS_INC(portId, txLock);
	qStatus = IX_QMGR_Q_OVERFLOW;
    }
    return qStatus;
}

/* write to qmgr if possible and report an overflow if not possible
 * Use a fast lock to protect the queue write.
 * This way, the Rx feature is reentrant.
 */
PRIVATE IX_STATUS
ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, UINT32 qBuffer)
{
    IX_STATUS qStatus;
    if (ixOsalFastMutexTryLock(&rxWriteMutex[portId]) == IX_SUCCESS)
    {
	qStatus = ixQMgrQWrite(
	       IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId),
	       &qBuffer);
#ifndef NDEBUG
	if (qStatus != IX_SUCCESS)
	{
	    RX_STATS_INC(portId, rxFreeOverflow);
	}
#endif
	ixOsalFastMutexUnlock(&rxWriteMutex[portId]);
    }
    else
    {
	RX_STATS_INC(portId, rxFreeLock);
	qStatus = IX_QMGR_Q_OVERFLOW;
    }
    return qStatus;
}

/*
 * Set the priority and write to a qmgr queue.
 */
PRIVATE IX_STATUS
ixEthAccQmgrTxWrite(IxEthAccPortId portId, UINT32 qBuffer, UINT32 priority)
{
    /* fill the priority field */
    qBuffer |= (priority << IX_ETHNPE_QM_Q_FIELD_PRIOR_R);

    return ixEthAccQmgrLockTxWrite(portId, qBuffer);
}

/**
 *
 * @brief This function will discover the highest priority S/W Tx Q that
 *        has entries in it
 *
 * @param portId - (in) the id of the port whose S/W Tx queues are to be searched
 *        priorityPtr - (out) the priority of the highest priority occupied q will be written
 *                      here
 *
 * @return IX_ETH_ACC_SUCCESS if an occupied Q is found
 *         IX_ETH_ACC_FAIL if no Q has entries
 *
 * @internal
 */
PRIVATE IxEthAccStatus
ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId,
				IxEthAccTxPriority *priorityPtr)
{
    if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline
	== FIFO_NO_PRIORITY)
    {
	if(IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
	       ixEthAccTxData.txQ[IX_ETH_ACC_TX_DEFAULT_PRIORITY]))
	{
	    return IX_ETH_ACC_FAIL;
	}
	else
	{
	    *priorityPtr = IX_ETH_ACC_TX_DEFAULT_PRIORITY;
	    TX_STATS_INC(portId,txPriority[*priorityPtr]);
	    return IX_ETH_ACC_SUCCESS;
	}
    }
    else
    {
	IxEthAccTxPriority highestPriority = IX_ETH_ACC_TX_PRIORITY_7;
	while(1)
	{
	    if(!IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
	       ixEthAccTxData.txQ[highestPriority]))
	    {

		*priorityPtr = highestPriority;
		TX_STATS_INC(portId,txPriority[highestPriority]);
		return IX_ETH_ACC_SUCCESS;

	    }
	    if (highestPriority == IX_ETH_ACC_TX_PRIORITY_0)
	    {
		return IX_ETH_ACC_FAIL;
	    }
	    highestPriority--;
	}
    }
}

/**
 *
 * @brief This function will take a buffer from a TX S/W Q and attempt
 *        to add it to the relevant TX H/W Q
 *
 * @param portId - the port whose TX queue is to be written to
 *        priority - identifies the queue from which the entry is to be read
 *
 * @internal
 */
PRIVATE IxEthAccStatus
ixEthAccTxFromSwQ(IxEthAccPortId portId,
		  IxEthAccTxPriority priority)
{
    IX_OSAL_MBUF        *mbuf;
    IX_STATUS	   qStatus;

    IX_OSAL_ENSURE((UINT32)priority <= (UINT32)7, "Invalid priority");

    IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(
	ixEthAccPortData[portId].ixEthAccTxData.txQ[priority],
	mbuf);

    if (mbuf != NULL)
    {
	/*
	 * Add the Tx buffer to the H/W Tx Q
	 * We do not need to flush here as it is already done
	 * in TxFrameSubmit().
	 */
	qStatus = ixEthAccQmgrTxWrite(
	      portId,
	      IX_OSAL_MMU_VIRT_TO_PHYS((UINT32)IX_ETHACC_NE_SHARED(mbuf)),
	      priority);

	if (qStatus == IX_SUCCESS)
	{
	    TX_STATS_INC(portId,txFromSwQOK);
	    return IX_SUCCESS;
	}
	else if (qStatus == IX_QMGR_Q_OVERFLOW)
	{
	    /*
	     * H/W Q overflow, need to save the buffer
	     * back on the s/w Q.
	     * we must put it back on the head of the q to avoid
	     * reordering packet tx
	     */
	    TX_STATS_INC(portId,txFromSwQDelayed);
	    IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
		ixEthAccPortData[portId].ixEthAccTxData.txQ[priority],
		mbuf);

	    /*enable Q notification*/
	    qStatus = ixQMgrNotificationEnable(
		IX_ETH_ACC_PORT_TO_TX_Q_ID(portId),
		IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId));

            if (qStatus != IX_SUCCESS && qStatus != IX_QMGR_WARNING)
            {
		TX_INC(portId,txUnexpectedError);
		IX_ETH_ACC_FATAL_LOG(
	            "ixEthAccTxFromSwQ:Unexpected Error: %u\n",
	            qStatus, 0, 0, 0, 0, 0);
            }
	}
	else
	{
	    TX_INC(portId,txUnexpectedError);

	    /* recovery attempt */
	    IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
		ixEthAccPortData[portId].ixEthAccTxData.txQ[priority],
		mbuf);

	    IX_ETH_ACC_FATAL_LOG(
		"ixEthAccTxFromSwQ:Error: unexpected QM status 0x%08X\n",
		qStatus, 0, 0, 0, 0, 0);
	}
    }
    else
    {
	/* sw queue is empty */
    }
    return IX_ETH_ACC_FAIL;
}

/**
 *
 * @brief This function will take a buffer from a RXfree S/W Q and attempt
 *        to add it to the relevant RxFree H/W Q
 *
 * @param portId - the port whose RXFree queue is to be written to
 *
 * @internal
 */
PRIVATE IxEthAccStatus
ixEthAccRxFreeFromSwQ(IxEthAccPortId portId)
{
    IX_OSAL_MBUF        *mbuf;
    IX_STATUS	   qStatus = IX_SUCCESS;

    IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(
	  ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
	  mbuf);
    if (mbuf != NULL)
    {
	/*
	 * Add The Rx Buffer to the H/W Free buffer Q if possible
	 */
	qStatus = ixEthAccQmgrLockRxWrite(portId,
		  IX_OSAL_MMU_VIRT_TO_PHYS(
			 (UINT32)IX_ETHACC_NE_SHARED(mbuf)));

	if (qStatus == IX_SUCCESS)
	{
	    RX_STATS_INC(portId,rxFreeRepFromSwQOK);
	    /*
	     * Buffer added to h/w Q.
	     */
	    return IX_SUCCESS;
	}
	else if (qStatus == IX_QMGR_Q_OVERFLOW)
	{
	    /*
	     * H/W Q overflow, need to save the buffer back on the s/w Q.
	     */
	    RX_STATS_INC(portId,rxFreeRepFromSwQDelayed);

	    IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
		   ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
		   mbuf);
	}
	else
	{
	    /* unexpected qmgr error */
	    RX_INC(portId,rxUnexpectedError);

	    IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
		    ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
		    mbuf);

	    IX_ETH_ACC_FATAL_LOG("IxEthAccRxFreeFromSwQ:Error: unexpected QM status 0x%08X\n",
				 qStatus, 0, 0, 0, 0, 0);
	}
    }
    else
    {
	/* sw queue is empty */
    }
    return IX_ETH_ACC_FAIL;
}


IX_ETH_ACC_PUBLIC
IxEthAccStatus ixEthAccInitDataPlane()
{
    UINT32 portId;

    /*
     * Initialize the service and register callback to other services.
     */

    IX_ETH_ACC_MEMSET(&ixEthAccDataStats,
		      0,
		      sizeof(ixEthAccDataStats));

    for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
    {
	ixOsalFastMutexInit(&txWriteMutex[portId]);
	ixOsalFastMutexInit(&rxWriteMutex[portId]);

	IX_ETH_ACC_MEMSET(&ixEthAccPortData[portId],
			  0,
			  sizeof(ixEthAccPortData[portId]));

	ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = FIFO_NO_PRIORITY;
    }

    return (IX_ETH_ACC_SUCCESS);
}


IX_ETH_ACC_PUBLIC
IxEthAccStatus ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId,
						  IxEthAccPortTxDoneCallback
						  txCallbackFn,
						  UINT32 callbackTag)
{
    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
	return (IX_ETH_ACC_FAIL);
    }
    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
    {
	return (IX_ETH_ACC_INVALID_PORT);
    }

/* HACK: removing this code to enable NPE-A preliminary testing
 *    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
 *    {
 *        IX_ETH_ACC_WARNING_LOG("ixEthAccPortTxDoneCallbackRegister: Unavailable Eth %d: Cannot register TxDone Callback.\n",(INT32)portId,0,0,0,0,0);
 *        return IX_ETH_ACC_SUCCESS ;
 *    }
 */

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }
    if (txCallbackFn == 0)
	/* Check for null function pointer here. */
    {
	return (IX_ETH_ACC_INVALID_ARG);
    }
    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = txCallbackFn;
    ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = callbackTag;
    return (IX_ETH_ACC_SUCCESS);
}


IX_ETH_ACC_PUBLIC
IxEthAccStatus ixEthAccPortRxCallbackRegister(IxEthAccPortId portId,
					      IxEthAccPortRxCallback
					      rxCallbackFn,
					      UINT32 callbackTag)
{
    IxEthAccPortId port;

    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
	return (IX_ETH_ACC_FAIL);
    }
    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
    {
	return (IX_ETH_ACC_INVALID_PORT);
    }

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("ixEthAccPortRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0);
        return IX_ETH_ACC_SUCCESS ;
    }

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }

    /* Check for null function pointer here. */
    if (rxCallbackFn == NULL)
    {
	return (IX_ETH_ACC_INVALID_ARG);
    }

    /* Check the user is not changing the callback type
     * when the port is enabled.
    */
    if (ixEthAccMacState[portId].portDisableState == ACTIVE)
    {
	for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++)
	{
	    if ((ixEthAccMacState[port].portDisableState == ACTIVE)
		&& (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == TRUE))
	    {
		/* one of the active ports has a different rx callback type.
		 * Changing the callback type when the port is enabled
		 * is not safe
		 */
		return (IX_ETH_ACC_INVALID_ARG);
	    }
	}
    }

    /* update the callback pointer : this is done before
     * registering the new qmgr callback
     */
    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = rxCallbackFn;
    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = callbackTag;

    /* update the qmgr callback for rx queues */
    if (ixEthAccQMgrRxCallbacksRegister(ixEthRxFrameQMCallback)
	!= IX_ETH_ACC_SUCCESS)
    {
	/* unexpected qmgr error */
        IX_ETH_ACC_FATAL_LOG("ixEthAccPortRxCallbackRegister: unexpected QMgr error, " \
            "could not register Rx single-buffer callback\n", 0, 0, 0, 0, 0, 0);

	RX_INC(portId,rxUnexpectedError);
	return (IX_ETH_ACC_INVALID_ARG);
    }

    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = FALSE;

    return (IX_ETH_ACC_SUCCESS);
}

IX_ETH_ACC_PUBLIC
IxEthAccStatus ixEthAccPortMultiBufferRxCallbackRegister(
			 IxEthAccPortId portId,
			 IxEthAccPortMultiBufferRxCallback
			 rxCallbackFn,
			 UINT32 callbackTag)
{
    IxEthAccPortId port;

    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
	return (IX_ETH_ACC_FAIL);
    }
    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
    {
	return (IX_ETH_ACC_INVALID_PORT);
    }

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("ixEthAccPortMultiBufferRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0);
        return IX_ETH_ACC_SUCCESS ;
    }

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }

    /* Check for null function pointer here. */
    if (rxCallbackFn == NULL)
    {
	return (IX_ETH_ACC_INVALID_ARG);
    }

    /* Check the user is not changing the callback type
     * when the port is enabled.
    */
    if (ixEthAccMacState[portId].portDisableState == ACTIVE)
    {
	for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++)
	{
	    if ((ixEthAccMacState[port].portDisableState == ACTIVE)
		&& (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == FALSE))
	    {
		/* one of the active ports has a different rx callback type.
		 * Changing the callback type when the port is enabled
		 * is not safe
		 */
		return (IX_ETH_ACC_INVALID_ARG);
	    }
	}
    }

    /* update the callback pointer : this is done before
     * registering the new qmgr callback
     */
    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = rxCallbackFn;
    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = callbackTag;

    /* update the qmgr callback for rx queues */
    if (ixEthAccQMgrRxCallbacksRegister(ixEthRxMultiBufferQMCallback)
	!= IX_ETH_ACC_SUCCESS)
    {
	/* unexpected qmgr error */
	RX_INC(portId,rxUnexpectedError);

        IX_ETH_ACC_FATAL_LOG("ixEthAccPortMultiBufferRxCallbackRegister: unexpected QMgr error, " \
            "could not register Rx multi-buffer callback\n", 0, 0, 0, 0, 0, 0);

	return (IX_ETH_ACC_INVALID_ARG);
    }

    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = TRUE;

    return (IX_ETH_ACC_SUCCESS);
}

IX_ETH_ACC_PUBLIC
IxEthAccStatus ixEthAccPortTxFrameSubmit(IxEthAccPortId portId,
					 IX_OSAL_MBUF *buffer,
					 IxEthAccTxPriority priority)
{
    IX_STATUS	qStatus = IX_SUCCESS;
    UINT32      qBuffer;
    IxEthAccTxPriority highestPriority;
    IxQMgrQStatus txQStatus;

#ifndef NDEBUG
    if (buffer == NULL)
    {
	return (IX_ETH_ACC_FAIL);
    }
    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
	return (IX_ETH_ACC_FAIL);
    }
    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
    {
	return (IX_ETH_ACC_INVALID_PORT);
    }

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_FATAL_LOG("ixEthAccPortTxFrameSubmit: Unavailable Eth %d: Cannot submit Tx Frame.\n",
			     (INT32)portId,0,0,0,0,0);
        return IX_ETH_ACC_PORT_UNINITIALIZED ;
    }

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }
    if ((UINT32)priority > (UINT32)IX_ETH_ACC_TX_PRIORITY_7)
    {
	return (IX_ETH_ACC_INVALID_ARG);
    }
#endif

    /*
     * Need to Flush the MBUF and its contents (data) as it may be
     * read from the NPE. Convert virtual addresses to physical addresses also.
     */
    qBuffer = ixEthAccMbufTxQPrepare(buffer);

    /*
     * If no fifo priority set on Xscale ...
     */
    if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline ==
	FIFO_NO_PRIORITY)
    {
	/*
	 * Add The Tx Buffer to the H/W Tx Q if possible
	 * (the priority is passed to the NPE, because
	 * the NPE is able to reorder the frames
	 * before transmission to the underlying hardware)
	 */
	qStatus = ixEthAccQmgrTxWrite(portId,
				      qBuffer,
				      IX_ETH_ACC_TX_DEFAULT_PRIORITY);

	if (qStatus == IX_SUCCESS)
	{
	    TX_STATS_INC(portId,txQOK);

	    /*
	     * "best case" scenario : Buffer added to h/w Q.
	     */
	    return (IX_SUCCESS);
	}
	else if (qStatus == IX_QMGR_Q_OVERFLOW)
	{
	    /*
	     * We were unable to write the buffer to the
	     * appropriate H/W Q,  Save it in the sw Q.
	     * (use the default priority queue regardless of
	     * input parameter)
	     */
	    priority = IX_ETH_ACC_TX_DEFAULT_PRIORITY;
	}
	else
	{
	    /* unexpected qmgr error */
	    TX_INC(portId,txUnexpectedError);
	    IX_ETH_ACC_FATAL_LOG(
		"ixEthAccPortTxFrameSubmit:Error: qStatus = %u\n",
		(UINT32)qStatus, 0, 0, 0, 0, 0);
	    return (IX_ETH_ACC_FAIL);
	}
    }
    else if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline ==
	     FIFO_PRIORITY)
    {

	/*
	 * For priority transmission, put the frame directly on the H/W queue
	 * if the H/W queue is empty, otherwise, put it in a S/W Q
	 */
	ixQMgrQStatusGet(IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), &txQStatus);
	if((txQStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) != 0)
	{
	    /*The tx queue is empty, check whether there are buffers on the s/w queues*/
	    if(ixEthAccTxSwQHighestPriorityGet(portId,  &highestPriority)
	       !=IX_ETH_ACC_FAIL)
	    {
		/*there are buffers on the s/w queues, submit them*/
		ixEthAccTxFromSwQ(portId, highestPriority);

		/* the queue was empty, 1 buffer is already supplied
		 * but is likely to be immediately transmitted and the
		 * hw queue is likely to be empty again, so submit
		 * more from the sw queues
		 */
		if(ixEthAccTxSwQHighestPriorityGet(portId,  &highestPriority)
		   !=IX_ETH_ACC_FAIL)
		{
		    ixEthAccTxFromSwQ(portId, highestPriority);
		    /*
		     * and force the buffer supplied to be placed
		     * on a priority queue
		     */
		    qStatus = IX_QMGR_Q_OVERFLOW;
		}
		else
		{
		    /*there are no buffers in the s/w queues, submit directly*/
		    qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority);
		}
	    }
	    else
	    {
		/*there are no buffers in the s/w queues, submit directly*/
		qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority);
	    }
	}
	else
	{
	    qStatus = IX_QMGR_Q_OVERFLOW;
	}
    }
    else
    {
	TX_INC(portId,txUnexpectedError);
	IX_ETH_ACC_FATAL_LOG(
	    "ixEthAccPortTxFrameSubmit:Error: wrong schedule discipline setup\n",
	    0, 0, 0, 0, 0, 0);
	return (IX_ETH_ACC_FAIL);
    }

    if(qStatus == IX_SUCCESS )
    {
	TX_STATS_INC(portId,txQOK);
	return IX_ETH_ACC_SUCCESS;
    }
    else if(qStatus == IX_QMGR_Q_OVERFLOW)
    {
	TX_STATS_INC(portId,txQDelayed);
	/*
	 * We were unable to write the buffer to the
	 * appropriate H/W Q,  Save it in a s/w Q.
	 */
	IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(
		ixEthAccPortData[portId].
		ixEthAccTxData.txQ[priority],
		buffer);

	qStatus = ixQMgrNotificationEnable(
		IX_ETH_ACC_PORT_TO_TX_Q_ID(portId),
		IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId));

        if (qStatus != IX_SUCCESS)
	{
	    if (qStatus == IX_QMGR_WARNING)
	    {
		/* notification is enabled for a queue
		 * which is already empty (the condition is already met)
		 * and there will be no more queue event to drain the sw queue
		 */
		TX_STATS_INC(portId,txLateNotificationEnabled);

		/* pull a buffer from the sw queue */
		if(ixEthAccTxSwQHighestPriorityGet(portId,  &highestPriority)
		   !=IX_ETH_ACC_FAIL)
		{
		    /*there are buffers on the s/w queues, submit from them*/
		    ixEthAccTxFromSwQ(portId, highestPriority);
		}
	    }
	    else
	    {
		TX_INC(portId,txUnexpectedError);
		IX_ETH_ACC_FATAL_LOG(
		     "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n",
		     qStatus, 0, 0, 0, 0, 0);
	    }
        }
    }
    else
    {
	TX_INC(portId,txUnexpectedError);
	IX_ETH_ACC_FATAL_LOG(
	     "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n",
	     qStatus, 0, 0, 0, 0, 0);
	return (IX_ETH_ACC_FAIL);
    }

    return (IX_ETH_ACC_SUCCESS);
}


/**
 *
 * @brief replenish: convert a chain of mbufs to the format
 *        expected by the NPE
 *
  */

IX_ETH_ACC_PUBLIC
IxEthAccStatus ixEthAccPortRxFreeReplenish(IxEthAccPortId portId,
					   IX_OSAL_MBUF *buffer)
{
    IX_STATUS	qStatus = IX_SUCCESS;
    UINT32      qBuffer;

    /*
     * Check buffer is valid.
     */

#ifndef NDEBUG
    /* check parameter value */
    if (buffer == 0)
    {
	return (IX_ETH_ACC_FAIL);
    }
    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
	return (IX_ETH_ACC_FAIL);
    }
    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
    {
	return (IX_ETH_ACC_INVALID_PORT);
    }

    /* check initialisation is done */
    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_FATAL_LOG(" ixEthAccPortRxFreeReplenish: Unavailable Eth %d: Cannot replenish Rx Free Q.\n",(INT32)portId,0,0,0,0,0);
        return IX_ETH_ACC_PORT_UNINITIALIZED ;
    }

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }
    /* check boundaries and constraints */
    if (IX_OSAL_MBUF_MLEN(buffer) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN)
    {
	return (IX_ETH_ACC_FAIL);
    }
#endif

    qBuffer = ixEthAccMbufRxQPrepare(buffer);

    /*
     * Add The Rx Buffer to the H/W Free buffer Q if possible
     */
    qStatus = ixEthAccQmgrLockRxWrite(portId, qBuffer);

    if (qStatus == IX_SUCCESS)
    {
	RX_STATS_INC(portId,rxFreeRepOK);
	/*
	 * Buffer added to h/w Q.
	 */
	return (IX_SUCCESS);
    }
    else if (qStatus == IX_QMGR_Q_OVERFLOW)
    {
	RX_STATS_INC(portId,rxFreeRepDelayed);
	/*
	 * We were unable to write the buffer to the approprate H/W Q,
	 * Save it in a s/w Q.
	 */
	IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(
	    ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
	    buffer);

	qStatus = ixQMgrNotificationEnable(
	    IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId),
	    IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(portId));

        if (qStatus != IX_SUCCESS)
	{
	    if (qStatus == IX_QMGR_WARNING)
	    {
		/* notification is enabled for a queue
		 * which is already empty (the condition is already met)
		 * and there will be no more queue event to drain the sw queue
		 * move an entry from the sw queue to the hw queue */
		RX_STATS_INC(portId,rxFreeLateNotificationEnabled);
		ixEthAccRxFreeFromSwQ(portId);
	    }
	    else
	    {
		RX_INC(portId,rxUnexpectedError);
		IX_ETH_ACC_FATAL_LOG(
		     "ixEthAccRxPortFreeReplenish:Error: %u\n",
		     qStatus, 0, 0, 0, 0, 0);
	    }
        }
    }
    else
    {
	RX_INC(portId,rxUnexpectedError);
	IX_ETH_ACC_FATAL_LOG(
	    "ixEthAccRxPortFreeReplenish:Error: qStatus = %u\n",
	    (UINT32)qStatus, 0, 0, 0, 0, 0);
        return(IX_ETH_ACC_FAIL);
    }
    return (IX_ETH_ACC_SUCCESS);
}


IX_ETH_ACC_PUBLIC
IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId,
						 IxEthAccSchedulerDiscipline
						 sched)
{
    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
    {
	return (IX_ETH_ACC_INVALID_PORT);
    }

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("ixEthAccTxSchedulingDisciplineSet: Unavailable Eth %d: Cannot set Tx Scheduling Discipline.\n",(INT32)portId,0,0,0,0,0);
        return IX_ETH_ACC_SUCCESS ;
    }

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }

    if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY)
    {
	return (IX_ETH_ACC_INVALID_ARG);
    }

    ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = sched;
    return (IX_ETH_ACC_SUCCESS);
}

IX_ETH_ACC_PUBLIC
IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline
						 sched)
{
    if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY)
    {
	return (IX_ETH_ACC_INVALID_ARG);
    }

    ixEthAccDataInfo.schDiscipline = sched;

    return (IX_ETH_ACC_SUCCESS);
}


/**
 * @fn ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr)
 *
 * @brief process incoming frame :
 *
 * @param @ref IxQMgrCallback IxQMgrMultiBufferCallback
 *
 * @return none
 *
 * @internal
 *
 */
IX_ETH_ACC_PRIVATE BOOL
ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr)
{
    UINT32 flags;
    IxEthDBStatus result;

#ifndef NDEBUG
    /* Prudent to at least check the port is within range */
    if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
    {
	ixEthAccDataStats.unexpectedError++;
	IX_ETH_ACC_FATAL_LOG(
	     "ixEthRxFrameProcess: Illegal port: %u\n",
	     (UINT32)portId, 0, 0, 0, 0, 0);
	return FALSE;
    }
#endif

    /* convert fields from mbuf header */
    ixEthAccMbufFromRxQ(mbufPtr);

    /* check about any special processing for this frame */
    flags = IX_ETHACC_NE_FLAGS(mbufPtr);
    if ((flags & (IX_ETHACC_NE_FILTERMASK | IX_ETHACC_NE_NEWSRCMASK)) == 0)
    {
	/* "best case" scenario : nothing special to do for this frame */
	return TRUE;
    }

#ifdef CONFIG_IXP425_COMPONENT_ETHDB
    /* if a new source MAC address is detected by the NPE,
     * update IxEthDB with the portId and the MAC address.
     */
    if ((flags & IX_ETHACC_NE_NEWSRCMASK & ixEthAccNewSrcMask) != 0)
    {
        result = ixEthDBFilteringDynamicEntryProvision(portId,
			  (IxEthDBMacAddr *) IX_ETHACC_NE_SOURCEMAC(mbufPtr));

	if (result != IX_ETH_DB_SUCCESS && result != IX_ETH_DB_FEATURE_UNAVAILABLE)
	{
            if ((ixEthAccMacState[portId].portDisableState == ACTIVE) && (result != IX_ETH_DB_BUSY))
            {
	        RX_STATS_INC(portId, rxUnexpectedError);
                IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to add source MAC \
                                    to the Learning/Filtering database\n", 0, 0, 0, 0, 0, 0);
            }
            else
            {
                /* we expect this to fail during PortDisable, as EthDB is disabled for
                 * that port and will refuse to learn new addresses
		 */
            }
	}
	else
	{
	    RX_STATS_INC(portId, rxUnlearnedMacAddress);
	}
    }
#endif

    /* check if this frame should have been filtered
     * by the NPE and take the appropriate action
     */
    if (((flags & IX_ETHACC_NE_FILTERMASK) != 0)
        && (ixEthAccMacState[portId].portDisableState == ACTIVE))
    {
        /* If the mbuf was allocated with a small data size, or the current data pointer is not
         * within the allocated data area, then the buffer is non-standard and has to be
         * replenished with the minimum size only
         */
        if( (IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN)
           || ((UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) > IX_OSAL_MBUF_MDATA(mbufPtr))
           || ((UINT8 *)(IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) +
              IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr))
               < IX_OSAL_MBUF_MDATA(mbufPtr)) )
        {
            /* set to minimum length */
            IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) =
                IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN;
        }
        else
        {
            /* restore original length */
            IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) =
                ( IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) -
                 (IX_OSAL_MBUF_MDATA(mbufPtr) - (UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr)) );
        }

        /* replenish from here */
        if (ixEthAccPortRxFreeReplenish(portId, mbufPtr) != IX_ETH_ACC_SUCCESS)
        {
                IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to replenish with filtered frame\
                                      on port %d\n", portId, 0, 0, 0, 0, 0);
        }

        RX_STATS_INC(portId, rxFiltered);

        /* indicate that frame should not be subjected to further processing */
        return FALSE;
    }

    return TRUE;
}


/**
 * @fn ixEthRxFrameQMCallback
 *
 * @brief receive callback for Frame receive Q from NPE
 *
 * Frames are passed one-at-a-time to the user
 *
 * @param @ref IxQMgrCallback
 *
 * @return none
 *
 * @internal
 *
 * Design note : while processing the entry X, entry X+1 is preloaded
 * into memory to reduce the number of stall cycles
 *
 */
void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
{
    IX_OSAL_MBUF    *mbufPtr;
    IX_OSAL_MBUF    *nextMbufPtr;
    UINT32     qEntry;
    UINT32     nextQEntry;
    UINT32     *qEntryPtr;
    UINT32     portId;
    UINT32     destPortId;
    UINT32     npeId;
    UINT32     rxQReadStatus;

    /*
     * Design note : entries are read in a buffer, This buffer contains
     * an extra zeroed entry so the loop will
     * always terminate on a null entry, whatever the result of Burst read is.
     */
    UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1];

    /*
     * Indication of the number of times the callback is used.
     */
    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter);

    do
    {
	/*
	 * Indication of the number of times the queue is drained
	 */
	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead);

	/* ensure the last entry of the array contains a zeroed value */
	qEntryPtr = rxQEntry;
	qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0;

	rxQReadStatus = ixQMgrQBurstRead(qId,
		 IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK,
		 qEntryPtr);

#ifndef NDEBUG
	if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW)
	    && (rxQReadStatus != IX_SUCCESS))
	{
	    ixEthAccDataStats.unexpectedError++;
	    /*major error*/
	    IX_ETH_ACC_FATAL_LOG(
		"ixEthRxFrameQMCallback:Error: %u\n",
		(UINT32)rxQReadStatus, 0, 0, 0, 0, 0);
	    return;
	}
#endif

	/* convert and preload the next entry
	 * (the conversion function takes care about null pointers which
	 * are used to mark the end of the loop)
	 */
	nextQEntry = *qEntryPtr;
	nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
			  IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);

	while(nextQEntry != 0)
	{
	    /* get the next entry */
	    qEntry = nextQEntry;
	    mbufPtr = nextMbufPtr;

#ifndef NDEBUG
	    if (mbufPtr == NULL)
	    {
		ixEthAccDataStats.unexpectedError++;
		IX_ETH_ACC_FATAL_LOG(
		    "ixEthRxFrameQMCallback: Null Mbuf Ptr\n",
		    0, 0, 0, 0, 0, 0);
		return;
	    }
#endif

	    /* convert the next entry
	     * (the conversion function takes care about null pointers which
	     * are used to mark the end of the loop)
	     */
	    nextQEntry = *(++qEntryPtr);
	    nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
			      IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);

	    /*
	     * Get Port and Npe ID from message.
	     */
	    npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK &
		      qEntry) >> IX_ETHNPE_QM_Q_FIELD_NPEID_R);
	    portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);

	    /* process frame, check the return code and skip the remaining of
	     * the loop if the frame is to be filtered out
	     */
            if (ixEthRxFrameProcess(portId, mbufPtr))
            {
	        /* destination portId for this packet */
	        destPortId = IX_ETHACC_NE_DESTPORTID(mbufPtr);

                if (destPortId != IX_ETH_DB_UNKNOWN_PORT)
                {
                    destPortId = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(destPortId);
                }

	        /* test if QoS is enabled in ethAcc
	        */
	        if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY)
	        {
		    /* check if there is a higher priority queue
		    * which may require processing and then process it.
		    */
		    if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES)
		    {
		        ixEthRxFrameQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId],
					    callbackId);
		    }
	        }

	        /*
	        * increment priority stats
	        */
	        RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]);

	        /*
	        * increment callback count stats
	        */
	        RX_STATS_INC(portId,rxFrameClientCallback);

	        /*
	        * Call user level callback.
	        */
	        ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn(
		    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag,
		    mbufPtr,
		    destPortId);
            }
	}
    } while (rxQReadStatus == IX_SUCCESS);
}

/**
 * @fn ixEthRxMultiBufferQMCallback
 *
 * @brief receive callback for Frame receive Q from NPE
 *
 * Frames are passed as an array to the user
 *
 * @param @ref IxQMgrCallback
 *
 * @return none
 *
 * @internal
 *
 * Design note : while processing the entry X, entry X+1 is preloaded
 * into memory to reduce the number of stall cycles
 *
 */
void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
{
    IX_OSAL_MBUF    *mbufPtr;
    IX_OSAL_MBUF    *nextMbufPtr;
    UINT32     qEntry;
    UINT32     nextQEntry;
    UINT32     *qEntryPtr;
    UINT32     portId;
    UINT32     npeId;
    UINT32     rxQReadStatus;
    /*
     * Design note : entries are read in a static buffer, This buffer contains
     * an extra zeroed entry so the loop will
     * always terminate on a null entry, whatever the result of Burst read is.
     */
    static UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1];
    static IX_OSAL_MBUF *rxMbufPortArray[IX_ETH_ACC_NUMBER_OF_PORTS][IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1];
    IX_OSAL_MBUF **rxMbufPtr[IX_ETH_ACC_NUMBER_OF_PORTS];

    for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
    {
	rxMbufPtr[portId] = rxMbufPortArray[portId];
    }

    /*
     * Indication of the number of times the callback is used.
     */
    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter);

    do
    {
	/*
	 * Indication of the number of times the queue is drained
	 */
	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead);

	/* ensure the last entry of the array contains a zeroed value */
	qEntryPtr = rxQEntry;
	qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0;

	rxQReadStatus = ixQMgrQBurstRead(qId,
		 IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK,
		 qEntryPtr);

#ifndef NDEBUG
	if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW)
	    && (rxQReadStatus != IX_SUCCESS))
	{
	    ixEthAccDataStats.unexpectedError++;
	    /*major error*/
	    IX_ETH_ACC_FATAL_LOG(
		"ixEthRxFrameMultiBufferQMCallback:Error: %u\n",
		(UINT32)rxQReadStatus, 0, 0, 0, 0, 0);
	    return;
	}
#endif

	/* convert and preload the next entry
	 * (the conversion function takes care about null pointers which
	 * are used to mark the end of the loop)
	 */
	nextQEntry = *qEntryPtr;
	nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
			  IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);

	while(nextQEntry != 0)
	{
	    /* get the next entry */
	    qEntry = nextQEntry;
	    mbufPtr = nextMbufPtr;

#ifndef NDEBUG
	    if (mbufPtr == NULL)
	    {
		ixEthAccDataStats.unexpectedError++;
		IX_ETH_ACC_FATAL_LOG(
		    "ixEthRxFrameMultiBufferQMCallback:Error: Null Mbuf Ptr\n",
		    0, 0, 0, 0, 0, 0);
		return;
	    }
#endif

	    /* convert the next entry
	     * (the conversion function takes care about null pointers which
	     * are used to mark the end of the loop)
	     */
	    nextQEntry = *(++qEntryPtr);
	    nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
			      IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);

	    /*
	     * Get Port and Npe ID from message.
	     */
	    npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK &
		      qEntry) >>
		     IX_ETHNPE_QM_Q_FIELD_NPEID_R);
	    portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);

	    /* skip the remaining of the loop if the frame is
	     * to be filtered out
	     */
	    if (ixEthRxFrameProcess(portId, mbufPtr))
	    {
		/* store a mbuf pointer in an array */
		*rxMbufPtr[portId]++ = mbufPtr;

		/*
		 * increment priority stats
		 */
		RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]);
	    }

	    /* test for QoS enabled in ethAcc */
	    if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY)
	    {
		/* check if there is a higher priority queue
		 * which may require processing and then process it.
		 */
		if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES)
		{
		    ixEthRxMultiBufferQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId],
						 callbackId);
		}
	    }
	}

	/* check if any of the the arrays contains any entry */
	for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
	{
	    if (rxMbufPtr[portId] != rxMbufPortArray[portId])
	    {
		/* add a last NULL pointer at the end of the
		 * array of mbuf pointers
		 */
		*rxMbufPtr[portId] = NULL;

		/*
		 * increment callback count stats
		 */
		RX_STATS_INC(portId,rxFrameClientCallback);

		/*
		 * Call user level callback with an array of
		 * buffers (NULL terminated)
		 */
		ixEthAccPortData[portId].ixEthAccRxData.
		    rxMultiBufferCallbackFn(
			    ixEthAccPortData[portId].ixEthAccRxData.
			           rxMultiBufferCallbackTag,
			    rxMbufPortArray[portId]);

		/* reset the buffer pointer to the beginning of
		 * the array
		 */
		rxMbufPtr[portId] = rxMbufPortArray[portId];
	    }
	}

    } while (rxQReadStatus == IX_SUCCESS);
}


/**
 * @brief  rxFree low event handler
 *
 */
void ixEthRxFreeQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
{
    IxEthAccPortId	portId = (IxEthAccPortId) callbackId;
    int		        lockVal;
    UINT32		maxQWritesToPerform = IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD;
    IX_STATUS	        qStatus = IX_SUCCESS;

    /*
     * We have reached a low threshold on one of the Rx Free Qs
     */

    /*note that due to the fact that we are working off an Empty threshold, this callback
      need only write a single entry to the Rx Free queue in order to re-arm the notification
    */

    RX_STATS_INC(portId,rxFreeLowCallback);

    /*
     * Get buffers from approprite S/W Rx freeBufferList Q.
     */

#ifndef NDEBUG
    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
    {
	ixEthAccDataStats.unexpectedError++;
	IX_ETH_ACC_FATAL_LOG(
	    "ixEthRxFreeQMCallback:Error: Invalid Port 0x%08X\n",
	    portId, 0, 0, 0, 0, 0);
	return;
    }
#endif
    IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);
    if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
					ixEthAccRxData.freeBufferList))
    {
	/*
	 * Turn off Q callback notification for Q in Question.
	 */
	qStatus = ixQMgrNotificationDisable(
	    IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId));


	IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);

	if (qStatus != IX_SUCCESS)
	{
	    RX_INC(portId,rxUnexpectedError);
	    IX_ETH_ACC_FATAL_LOG(
		"ixEthRxFreeQMCallback:Error: unexpected QM status 0x%08X\n",
		qStatus, 0, 0, 0, 0, 0);
	    return;
	}
    }
    else
    {
	IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
	/*
	 * Load the H/W Q with buffers from the s/w Q.
	 */

	do
	{
	    /*
	     * Consume Q entries. - Note Q contains Physical addresss,
	     * and have already been flushed to memory,
	     * And endianess converted if required.
	     */
	    if (ixEthAccRxFreeFromSwQ(portId) != IX_SUCCESS)
	    {
		/*
		 * No more entries in s/w Q.
		 * Turn off Q callback indication
		 */

		IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);
		if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
		    ixEthAccRxData.freeBufferList))
		{
		    qStatus = ixQMgrNotificationDisable(
			IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId));
		}
		IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
		break;
	    }
	}
	while (--maxQWritesToPerform);
    }
}
/**
 * @fn Tx queue low event handler
 *
 */
void
ixEthTxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
{
    IxEthAccPortId portId = (IxEthAccPortId) callbackId;
    int		   lockVal;
    UINT32	   maxQWritesToPerform = IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK;
    IX_STATUS	   qStatus = IX_SUCCESS;
    IxEthAccTxPriority highestPriority;


    /*
     * We have reached a low threshold on the Tx Q, and are being asked to
     * supply a buffer for transmission from our S/W TX queues
     */
    TX_STATS_INC(portId,txLowThreshCallback);

    /*
     * Get buffers from approprite Q.
     */

#ifndef NDEBUG
    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
    {
	ixEthAccDataStats.unexpectedError++;
	IX_ETH_ACC_FATAL_LOG(
	    "ixEthTxFrameQMCallback:Error: Invalid Port 0x%08X\n",
	    portId, 0, 0, 0, 0, 0);
	return;
    }
#endif

    do
    {
	/*
	 * Consume Q entries. - Note Q contains Physical addresss,
	 * and have already been flushed to memory,
	 * and endianess already sone if required.
	 */

	IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);

	if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) ==
	   IX_ETH_ACC_FAIL)
	{
	    /*
	     * No more entries in s/w Q.
	     * Turn off Q callback indication
	     */
	    qStatus = ixQMgrNotificationDisable(
		IX_ETH_ACC_PORT_TO_TX_Q_ID(portId));

	    IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);

	    if (qStatus != IX_SUCCESS)
	    {
		ixEthAccDataStats.unexpectedError++;
		IX_ETH_ACC_FATAL_LOG(
		    "ixEthTxFrameQMCallback:Error: unexpected QM status 0x%08X\n",
		    qStatus, 0, 0, 0, 0, 0);
	    }

	    return;
	}
	else
	{
	    IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
	    if (ixEthAccTxFromSwQ(portId,highestPriority)!=IX_SUCCESS)
	    {
                /* nothing left in the sw queue or the hw queues are
                * full. There is no point to continue to drain the
                * sw queues
                */
		return;
	    }
	}
    }
    while (--maxQWritesToPerform);
}

/**
 * @brief TxDone event handler
 *
 * Design note : while processing the entry X, entry X+1 is preloaded
 * into memory to reduce the number of stall cycles
 *
 */

void
ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
{
    IX_OSAL_MBUF    *mbufPtr;
    UINT32     qEntry;
    UINT32     *qEntryPtr;
    UINT32     txDoneQReadStatus;
    UINT32     portId;
    UINT32     npeId;

    /*
     * Design note : entries are read in a static buffer, This buffer contains
     * an extra entyry (which is zeroed by the compiler), so the loop will
     * always terminate on a null entry, whatever the result of Burst read is.
     */
    static UINT32 txDoneQEntry[IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK + 1];

    /*
     * Indication that Tx frames have been transmitted from the NPE.
     */

    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.txDoneCallbackCounter);

    do{
	qEntryPtr = txDoneQEntry;
	txDoneQReadStatus = ixQMgrQBurstRead(IX_ETH_ACC_TX_FRAME_DONE_ETH_Q,
		     IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK,
		     qEntryPtr);

#ifndef NDEBUG
	if (txDoneQReadStatus != IX_QMGR_Q_UNDERFLOW
	    && (txDoneQReadStatus != IX_SUCCESS))
	{
	    /*major error*/
	    ixEthAccDataStats.unexpectedError++;
	    IX_ETH_ACC_FATAL_LOG(
		"ixEthTxFrameDoneQMCallback:Error: %u\n",
		(UINT32)txDoneQReadStatus, 0, 0, 0, 0, 0);
	    return;
	}
#endif

	qEntry = *qEntryPtr;

	while(qEntry != 0)
	{
	    mbufPtr = ixEthAccEntryFromQConvert(qEntry,
		      IX_ETHNPE_QM_Q_TXENET_ADDR_MASK);

#ifndef NDEBUG
	    if (mbufPtr == NULL)
	    {
		ixEthAccDataStats.unexpectedError++;
		IX_ETH_ACC_FATAL_LOG(
		    "ixEthTxFrameDoneQMCallback:Error: Null Mbuf Ptr\n",
		    0, 0, 0, 0, 0, 0);
		return;
	    }
#endif

	    /* endianness conversions and stats updates */
	    ixEthAccMbufFromTxQ(mbufPtr);

	    /*
	     * Get NPE id from message, then convert to portId.
	     */
	    npeId = ((IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK &
		       qEntry) >>
		      IX_ETHNPE_QM_Q_FIELD_NPEID_R);
	    portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);

#ifndef NDEBUG
	    /* Prudent to at least check the port is within range */
	    if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
	    {
		ixEthAccDataStats.unexpectedError++;
		IX_ETH_ACC_FATAL_LOG(
		    "ixEthTxFrameDoneQMCallback: Illegal port: %u\n",
		    (UINT32)portId, 0, 0, 0, 0, 0);
		return;
	    }
#endif

	    TX_STATS_INC(portId,txDoneClientCallback);

	    /*
	     * Call user level callback.
	     */
	    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn(
		ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag,
		mbufPtr);

	    /* move to next queue entry */
	    qEntry = *(++qEntryPtr);

	}
    } while( txDoneQReadStatus == IX_SUCCESS );
}

IX_ETH_ACC_PUBLIC
void ixEthAccDataPlaneShow(void)
{
    UINT32 numTx0Entries;
    UINT32 numTx1Entries;
    UINT32 numTxDoneEntries;
    UINT32 numRxEntries;
    UINT32 numRxFree0Entries;
    UINT32 numRxFree1Entries;
    UINT32 portId;
#ifdef __ixp46X
    UINT32 numTx2Entries;
    UINT32 numRxFree2Entries;
#endif
#ifndef NDEBUG
    UINT32 priority;
    UINT32 numBuffersInRx=0;
    UINT32 numBuffersInTx=0;
    UINT32 numBuffersInSwQ=0;
    UINT32 totalBuffers=0;
    UINT32 rxFreeCallbackCounter = 0;
    UINT32 txCallbackCounter = 0;
#endif
    UINT32 key;

    /* snapshot of stats */
    IxEthAccTxDataStats tx[IX_ETH_ACC_NUMBER_OF_PORTS];
    IxEthAccRxDataStats rx[IX_ETH_ACC_NUMBER_OF_PORTS];
    IxEthAccDataPlaneStats stats;

    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
	return;
    }

    /* get a reliable snapshot */
    key = ixOsalIrqLock();

    numTx0Entries = 0;
    ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET0_Q, &numTx0Entries);
    numTx1Entries = 0;
    ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET1_Q, &numTx1Entries);
    numTxDoneEntries = 0;
    ixQMgrQNumEntriesGet( IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, &numTxDoneEntries);
    numRxEntries = 0;
    ixEthAccQMgrRxQEntryGet(&numRxEntries);
    numRxFree0Entries = 0;
    ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, &numRxFree0Entries);
    numRxFree1Entries = 0;
    ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, &numRxFree1Entries);

#ifdef __ixp46X
    numTx2Entries = 0;
    ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET2_Q, &numTx2Entries);
    numRxFree2Entries = 0;
    ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, &numRxFree2Entries);
#endif

    for(portId=IX_ETH_PORT_1; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
    {
	memcpy(&tx[portId],
	       &ixEthAccPortData[portId].ixEthAccTxData.stats,
	       sizeof(tx[portId]));
	memcpy(&rx[portId],
	       &ixEthAccPortData[portId].ixEthAccRxData.stats,
	       sizeof(rx[portId]));
    }
    memcpy(&stats, &ixEthAccDataStats, sizeof(stats));

    ixOsalIrqUnlock(key);

#ifdef NDEBUG
    printf("Detailed statistics collection not supported in this load\n");
#endif

    /* print snapshot */
    for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
    {
        /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
        if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
	     (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
	    || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
        {
                if ((IX_ETH_PORT_1 == portId) &&
                    (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
                     IX_FEATURE_CTRL_COMPONENT_DISABLED))
                {
                   continue ;
                }
                if ((IX_ETH_PORT_2 == portId) &&
                    (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
                     IX_FEATURE_CTRL_COMPONENT_DISABLED))
                {
                    continue ;
                }
                if ((IX_ETH_PORT_3 == portId) &&
                    (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
                     IX_FEATURE_CTRL_COMPONENT_DISABLED))
                {
                    continue ;
                }
        }

	printf("PORT %u --------------------------------\n",
	       portId);
#ifndef NDEBUG
	printf("Tx Done Frames                : %u\n",
	       tx[portId].txDoneClientCallback +
	       tx[portId].txDoneSwQDuringDisable +
	       tx[portId].txDoneDuringDisable);
	printf("Tx Frames                     : %u\n",
	       tx[portId].txQOK + tx[portId].txQDelayed);
	printf("Tx H/W Q Added OK             : %u\n",
	       tx[portId].txQOK);
	printf("Tx H/W Q Delayed              : %u\n",
	       tx[portId].txQDelayed);
	printf("Tx From S/W Q Added OK        : %u\n",
	       tx[portId].txFromSwQOK);
	printf("Tx From S/W Q Delayed         : %u\n",
	       tx[portId].txFromSwQDelayed);
	printf("Tx Overflow                   : %u\n",
	       tx[portId].txOverflow);
	printf("Tx Mutual Lock                : %u\n",
	       tx[portId].txLock);
	printf("Tx Late Ntf Enabled           : %u\n",
	       tx[portId].txLateNotificationEnabled);
	printf("Tx Low Thresh CB              : %u\n",
	       tx[portId].txLowThreshCallback);
	printf("Tx Done from H/W Q (Disable)  : %u\n",
	       tx[portId].txDoneDuringDisable);
	printf("Tx Done from S/W Q (Disable)  : %u\n",
	       tx[portId].txDoneSwQDuringDisable);
	for (priority = IX_ETH_ACC_TX_PRIORITY_0;
	     priority <= IX_ETH_ACC_TX_PRIORITY_7;
	     priority++)
	{
	    if (tx[portId].txPriority[priority])
	    {
		printf("Tx Priority %u                 : %u\n",
		       priority,
		       tx[portId].txPriority[priority]);
	    }
	}
#endif
	printf("Tx unexpected errors          : %u (should be 0)\n",
	       tx[portId].txUnexpectedError);

#ifndef NDEBUG
	printf("Rx Frames                     : %u\n",
	       rx[portId].rxFrameClientCallback +
	       rx[portId].rxSwQDuringDisable+
	       rx[portId].rxDuringDisable);
	printf("Rx Free Replenish             : %u\n",
	       rx[portId].rxFreeRepOK + rx[portId].rxFreeRepDelayed);
	printf("Rx Free H/W Q Added OK        : %u\n",
	       rx[portId].rxFreeRepOK);
	printf("Rx Free H/W Q Delayed         : %u\n",
	       rx[portId].rxFreeRepDelayed);
	printf("Rx Free From S/W Q Added OK   : %u\n",
	       rx[portId].rxFreeRepFromSwQOK);
	printf("Rx Free From S/W Q Delayed    : %u\n",
	       rx[portId].rxFreeRepFromSwQDelayed);
	printf("Rx Free Overflow              : %u\n",
	       rx[portId].rxFreeOverflow);
	printf("Rx Free Mutual Lock           : %u\n",
	       rx[portId].rxFreeLock);
	printf("Rx Free Late Ntf Enabled      : %u\n",
	       rx[portId].rxFreeLateNotificationEnabled);
	printf("Rx Free Low CB                : %u\n",
	       rx[portId].rxFreeLowCallback);
	printf("Rx From H/W Q (Disable)       : %u\n",
	       rx[portId].rxDuringDisable);
	printf("Rx From S/W Q (Disable)       : %u\n",
	       rx[portId].rxSwQDuringDisable);
	printf("Rx unlearned Mac Address      : %u\n",
	       rx[portId].rxUnlearnedMacAddress);
        printf("Rx Filtered (Rx => RxFree)    : %u\n",
            rx[portId].rxFiltered);

	for (priority = IX_ETH_ACC_TX_PRIORITY_0;
	     priority <= IX_ETH_ACC_TX_PRIORITY_7;
	     priority++)
	{
	    if (rx[portId].rxPriority[priority])
	    {
		printf("Rx Priority %u                 : %u\n",
		       priority,
		       rx[portId].rxPriority[priority]);
	    }
	}
#endif
	printf("Rx unexpected errors          : %u (should be 0)\n",
	       rx[portId].rxUnexpectedError);

#ifndef NDEBUG
	numBuffersInTx = tx[portId].txQOK +
	    tx[portId].txQDelayed -
	    tx[portId].txDoneClientCallback -
	    tx[portId].txDoneSwQDuringDisable -
	    tx[portId].txDoneDuringDisable;

	printf("# Tx Buffers currently for transmission : %u\n",
	       numBuffersInTx);

	numBuffersInRx = rx[portId].rxFreeRepOK +
	    rx[portId].rxFreeRepDelayed -
	    rx[portId].rxFrameClientCallback -
	    rx[portId].rxSwQDuringDisable -
	    rx[portId].rxDuringDisable;

	printf("# Rx Buffers currently for reception    : %u\n",
	       numBuffersInRx);

	totalBuffers += numBuffersInRx + numBuffersInTx;
#endif
    }

    printf("---------------------------------------\n");

#ifndef NDEBUG
    printf("\n");
    printf("Mbufs :\n");
    printf("Tx Unchained mbufs            : %u\n",
	   stats.unchainedTxMBufs);
    printf("Tx Chained bufs               : %u\n",
	   stats.chainedTxMBufs);
    printf("TxDone Unchained mbufs        : %u\n",
	   stats.unchainedTxDoneMBufs);
    printf("TxDone Chained bufs           : %u\n",
	   stats.chainedTxDoneMBufs);
    printf("RxFree Unchained mbufs        : %u\n",
	   stats.unchainedRxFreeMBufs);
    printf("RxFree Chained bufs           : %u\n",
	   stats.chainedRxFreeMBufs);
    printf("Rx Unchained mbufs            : %u\n",
	   stats.unchainedRxMBufs);
    printf("Rx Chained bufs               : %u\n",
	   stats.chainedRxMBufs);

    printf("\n");
    printf("Software queue usage :\n");
    printf("Buffers added to S/W Q        : %u\n",
	   stats.addToSwQ);
    printf("Buffers removed from S/W Q    : %u\n",
	   stats.removeFromSwQ);

    printf("\n");
    printf("Hardware queues callbacks :\n");

    for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
    {
	rxFreeCallbackCounter += rx[portId].rxFreeLowCallback;
	txCallbackCounter += tx[portId].txLowThreshCallback;
    }
    printf("Tx Done QM Callback invoked   : %u\n",
	   stats.txDoneCallbackCounter);
    printf("Tx QM Callback invoked        : %u\n",
	   txCallbackCounter);
    printf("Rx QM Callback invoked        : %u\n",
	   stats.rxCallbackCounter);
    printf("Rx QM Callback burst read     : %u\n",
	   stats.rxCallbackBurstRead);
    printf("Rx Free QM Callback invoked   : %u\n",
	   rxFreeCallbackCounter);
#endif
    printf("Unexpected errors in CB       : %u (should be 0)\n",
	   stats.unexpectedError);
    printf("\n");

    printf("Hardware queues levels :\n");
    printf("Transmit Port 1 Q             : %u \n",numTx0Entries);
    printf("Transmit Port 2 Q             : %u \n",numTx1Entries);
#ifdef __ixp46X
    printf("Transmit Port 3 Q             : %u \n",numTx2Entries);
#endif
    printf("Transmit Done Q               : %u \n",numTxDoneEntries);
    printf("Receive Q                     : %u \n",numRxEntries);
    printf("Receive Free Port 1 Q         : %u \n",numRxFree0Entries);
    printf("Receive Free Port 2 Q         : %u \n",numRxFree1Entries);
#ifdef __ixp46X
    printf("Receive Free Port 3 Q         : %u \n",numRxFree2Entries);
#endif

#ifndef NDEBUG
    printf("\n");
    printf("# Total Buffers accounted for : %u\n",
	   totalBuffers);

    numBuffersInSwQ = ixEthAccDataStats.addToSwQ -
	ixEthAccDataStats.removeFromSwQ;

    printf("    Buffers in S/W Qs         : %u\n",
	   numBuffersInSwQ);
    printf("    Buffers in H/W Qs or NPEs : %u\n",
	   totalBuffers - numBuffersInSwQ);
#endif

    printf("Rx QoS Discipline             : %s\n",
	   (ixEthAccDataInfo.schDiscipline ==
	    FIFO_PRIORITY ) ? "Enabled" : "Disabled");

    for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
    {
	printf("Tx QoS Discipline port %u      : %s\n",
	       portId,
	       (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline ==
		FIFO_PRIORITY ) ? "Enabled" : "Disabled");
    }
    printf("\n");
}





