/**
 * @file IxEthAccMac.c
 *
 * @author Intel Corporation
 * @date
 *
 * @brief  MAC control functions
 *
 * Design Notes:
 *
 * @par
 * IXP400 SW Release version 2.0
 *
 * -- Copyright Notice --
 *
 * @par
 * Copyright 2001-2005, Intel Corporation.
 * All rights reserved.
 *
 * @par
 * SPDX-License-Identifier:	BSD-3-Clause
 * @par
 * -- End of Copyright Notice --
 */

#include "IxOsal.h"
#include "IxNpeMh.h"
#ifdef CONFIG_IXP425_COMPONENT_ETHDB
#include "IxEthDB.h"
#endif
#include "IxEthDBPortDefs.h"
#include "IxEthNpe.h"
#include "IxEthAcc.h"
#include "IxEthAccDataPlane_p.h"
#include "IxEthAcc_p.h"
#include "IxEthAccMac_p.h"

/* Maximum number of retries during ixEthAccPortDisable, which
 * is approximately 10 seconds
*/
#define IX_ETH_ACC_MAX_RETRY 500

/* Maximum number of retries during ixEthAccPortDisable when expecting
 * timeout
 */
#define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5

#define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \
    do                                                           \
    {                                                            \
        if(!IX_ETH_ACC_IS_PORT_VALID(portId))   \
        {                                                        \
	    return IX_ETH_ACC_INVALID_PORT;                      \
        }                                                        \
    } while(0)

PUBLIC IxEthAccMacState ixEthAccMacState[IX_ETH_ACC_NUMBER_OF_PORTS];

PRIVATE UINT32 ixEthAccMacBase[IX_ETH_ACC_NUMBER_OF_PORTS];

/*Forward function declarations*/
PRIVATE void
ixEthAccPortDisableRx (IxEthAccPortId portId,
		       IX_OSAL_MBUF * mBufPtr,
		       BOOL useMultiBufferCallback);

PRIVATE void
ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
				   IX_OSAL_MBUF * mBufPtr,
				   BOOL useMultiBufferCallback);

PRIVATE void
ixEthAccPortDisableTxDone (UINT32 cbTag,
			   IX_OSAL_MBUF *mbuf);

PRIVATE void
ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag,
				    IX_OSAL_MBUF *mbuf);

PRIVATE void
ixEthAccPortDisableRxCallback (UINT32 cbTag,
			       IX_OSAL_MBUF * mBufPtr,
			       UINT32 learnedPortId);

PRIVATE void
ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
					  IX_OSAL_MBUF **mBufPtr);

PRIVATE IxEthAccStatus
ixEthAccPortDisableTryTransmit(UINT32 portId);

PRIVATE IxEthAccStatus
ixEthAccPortDisableTryReplenish(UINT32 portId);

PRIVATE IxEthAccStatus
ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
				    IxEthAccMacAddr *macAddr);

PRIVATE IxEthAccStatus
ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
				   IxEthAccMacAddr *macAddr);

PRIVATE void
ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
				    IxNpeMhMessage msg);

PRIVATE void
ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
					 IxNpeMhMessage msg);

PRIVATE void
ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
				    IxNpeMhMessage msg);

PRIVATE void
ixEthAccMulticastAddressSet(IxEthAccPortId portId);

PRIVATE BOOL
ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
		 IxEthAccMacAddr *macAddr2);

PRIVATE void
ixEthAccMacPrint(IxEthAccMacAddr *m);

PRIVATE void
ixEthAccMacStateUpdate(IxEthAccPortId portId);

IxEthAccStatus
ixEthAccMacMemInit(void)
{
    ixEthAccMacBase[IX_ETH_PORT_1] =
	(UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE,
				 IX_OSAL_IXP400_ETHA_MAP_SIZE);
    ixEthAccMacBase[IX_ETH_PORT_2] =
	(UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE,
				 IX_OSAL_IXP400_ETHB_MAP_SIZE);
#ifdef __ixp46X
    ixEthAccMacBase[IX_ETH_PORT_3] =
	(UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_2_BASE,
				 IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE);
    if (ixEthAccMacBase[IX_ETH_PORT_3] == 0)
    {
	ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
		  IX_OSAL_LOG_DEV_STDOUT,
		  "EthAcc: Could not map MAC I/O memory\n",
		  0, 0, 0, 0, 0 ,0);

	return IX_ETH_ACC_FAIL;
    }
#endif

    if (ixEthAccMacBase[IX_ETH_PORT_1] == 0
	|| ixEthAccMacBase[IX_ETH_PORT_2] == 0)
    {
	ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
		  IX_OSAL_LOG_DEV_STDOUT,
		  "EthAcc: Could not map MAC I/O memory\n",
		  0, 0, 0, 0, 0 ,0);

	return IX_ETH_ACC_FAIL;
    }

    return IX_ETH_ACC_SUCCESS;
}

void
ixEthAccMacUnload(void)
{
    IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_1]);
    IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_2]);
#ifdef __ixp46X
    IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_3]);
    ixEthAccMacBase[IX_ETH_PORT_3] = 0;
#endif
    ixEthAccMacBase[IX_ETH_PORT_2] = 0;
    ixEthAccMacBase[IX_ETH_PORT_1] = 0;
}

IxEthAccStatus
ixEthAccPortEnablePriv(IxEthAccPortId portId)
{
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);
        return IX_ETH_ACC_SUCCESS ;
    }

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
        printf("EthAcc: (Mac) cannot enable port %d, port not initialized\n", portId);
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }

    if (ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn == NULL)
    {
        /* TxDone callback not registered */
        printf("EthAcc: (Mac) cannot enable port %d, TxDone callback not registered\n", portId);
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }

    if ((ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn == NULL)
	&& (ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn == NULL))
    {
        /* Receive callback not registered */
        printf("EthAcc: (Mac) cannot enable port %d, Rx callback not registered\n", portId);
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }

    if(!ixEthAccMacState[portId].initDone)
    {
        printf("EthAcc: (Mac) cannot enable port %d, MAC address not set\n", portId);
	return (IX_ETH_ACC_MAC_UNINITIALIZED);
    }

    /* if the state is being set to what it is already at, do nothing*/
    if (ixEthAccMacState[portId].enabled)
    {
        return IX_ETH_ACC_SUCCESS;
    }

#ifdef CONFIG_IXP425_COMPONENT_ETHDB
    /* enable ethernet database for this port */
    if (ixEthDBPortEnable(portId) != IX_ETH_DB_SUCCESS)
    {
        printf("EthAcc: (Mac) cannot enable port %d, EthDB failure\n", portId);
        return IX_ETH_ACC_FAIL;
    }
#endif

    /* set the MAC core registers */
    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_CNTRL2,
	      IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RANDOM_SEED,
	      IX_ETH_ACC_RANDOM_SEED_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_THRESH_P_EMPTY,
	      IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_THRESH_P_FULL,
	      IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_DEFER,
	      IX_ETH_ACC_MAC_TX_DEFER_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_TWO_DEFER_1,
	      IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_TWO_DEFER_2,
	      IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_SLOT_TIME,
	      IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_INT_CLK_THRESH,
	      IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_BUF_SIZE_TX,
	      IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_CNTRL1,
	      IX_ETH_ACC_TX_CNTRL1_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RX_CNTRL1,
	      IX_ETH_ACC_RX_CNTRL1_DEFAULT);

    /* set the global state */
    ixEthAccMacState[portId].portDisableState = ACTIVE;
    ixEthAccMacState[portId].enabled = true;

    /* rewrite the setup (including mac filtering) depending
     * on current options
     */
    ixEthAccMacStateUpdate(portId);

    return IX_ETH_ACC_SUCCESS;
}

/*
 * PortDisable local variables. They contain the intermediate steps
 * while the port is being disabled and the buffers being drained out
 * of the NPE.
 */
typedef void (*IxEthAccPortDisableRx)(IxEthAccPortId portId,
				      IX_OSAL_MBUF * mBufPtr,
				      BOOL useMultiBufferCallback);
static IxEthAccPortRxCallback
ixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS];
static IxEthAccPortMultiBufferRxCallback
ixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS];
static IxEthAccPortDisableRx
ixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS];
static UINT32
ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
static UINT32
ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];

static IxEthAccPortTxDoneCallback
ixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS];
static UINT32
ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];

static UINT32
ixEthAccPortDisableUserBufferCount[IX_ETH_ACC_NUMBER_OF_PORTS];

/*
 * PortDisable private callbacks functions. They handle the user
 * traffic, and the special buffers (one for tx, one for rx) used
 * in portDisable.
 */
PRIVATE void
ixEthAccPortDisableTxDone(UINT32 cbTag,
			  IX_OSAL_MBUF *mbuf)
{
    IxEthAccPortId portId = (IxEthAccPortId)cbTag;
    volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;

    /* check for the special mbuf used in portDisable */
    if (mbuf == ixEthAccMacState[portId].portDisableTxMbufPtr)
    {
        *txState = TRANSMIT_DONE;
    }
    else
    {
	/* increment the count of user traffic during portDisable */
	ixEthAccPortDisableUserBufferCount[portId]++;

       /* call client TxDone function */
        ixEthAccPortDisableTxDoneFn[portId](ixEthAccPortDisableTxDoneCbTag[portId], mbuf);
    }
}

PRIVATE IxEthAccStatus
ixEthAccPortDisableTryTransmit(UINT32 portId)
{
    int key;
    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
    volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
    /* transmit the special buffer again if it is transmitted
     * and update the txState
     * This section is protected because the portDisable context
     * run an identical code, so the system keeps transmitting at the
     * maximum rate.
     */
    key = ixOsalIrqLock();
    if (*txState == TRANSMIT_DONE)
    {
	IX_OSAL_MBUF *mbufTxPtr = ixEthAccMacState[portId].portDisableTxMbufPtr;
	*txState = TRANSMIT;
	status = ixEthAccPortTxFrameSubmit(portId,
					   mbufTxPtr,
					   IX_ETH_ACC_TX_DEFAULT_PRIORITY);
    }
    ixOsalIrqUnlock(key);

    return status;
}

PRIVATE void
ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag,
				   IX_OSAL_MBUF *mbuf)
{
    IxEthAccPortId portId = (IxEthAccPortId)cbTag;

    /* call the callback which forwards the traffic to the client */
    ixEthAccPortDisableTxDone(cbTag, mbuf);

    /* try to transmit the buffer used in portDisable
     * if seen in TxDone
     */
    ixEthAccPortDisableTryTransmit(portId);
}

PRIVATE void
ixEthAccPortDisableRx (IxEthAccPortId portId,
		       IX_OSAL_MBUF * mBufPtr,
		       BOOL useMultiBufferCallback)
{
    volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
    IX_OSAL_MBUF *mNextPtr;

    while (mBufPtr)
    {
	mNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr);
	IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr) = NULL;

	/* check for the special mbuf used in portDisable */
	if (mBufPtr == ixEthAccMacState[portId].portDisableRxMbufPtr)
	{
            *rxState = RECEIVE;
	}
	else
	{
	    /* increment the count of user traffic during portDisable */
	    ixEthAccPortDisableUserBufferCount[portId]++;

	    /* reset the received payload length during portDisable */
	    IX_OSAL_MBUF_MLEN(mBufPtr)    = 0;
	    IX_OSAL_MBUF_PKT_LEN(mBufPtr) = 0;

	    if (useMultiBufferCallback)
	    {
		/* call the user callback with one unchained
		 * buffer, without payload. A small array is built
		 * to be used as a parameter (the user callback expects
		 * to receive an array ended by a NULL pointer.
		 */
		IX_OSAL_MBUF *mBufPtrArray[2];

		mBufPtrArray[0] = mBufPtr;
		mBufPtrArray[1] = NULL;
		ixEthAccPortDisableMultiBufferFn[portId](
			 ixEthAccPortDisableMultiBufferCbTag[portId],
			 mBufPtrArray);
	    }
	    else
	    {
		/* call the user callback with a unchained
		 * buffer, without payload and the destination port is
		 * unknown.
		 */
		ixEthAccPortDisableFn[portId](
		      ixEthAccPortDisableCbTag[portId],
		      mBufPtr,
		      IX_ETH_DB_UNKNOWN_PORT /* port not found */);
	    }
        }

        mBufPtr = mNextPtr;
    }
}

PRIVATE IxEthAccStatus
ixEthAccPortDisableTryReplenish(UINT32 portId)
{
    int key;
    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
    volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
    /* replenish with the special buffer again if it is received
     * and update the rxState
     * This section is protected because the portDisable context
     * run an identical code, so the system keeps replenishing at the
     * maximum rate.
     */
    key = ixOsalIrqLock();
    if (*rxState == RECEIVE)
    {
	IX_OSAL_MBUF *mbufRxPtr = ixEthAccMacState[portId].portDisableRxMbufPtr;
	*rxState = REPLENISH;
	IX_OSAL_MBUF_MLEN(mbufRxPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;
	status = ixEthAccPortRxFreeReplenish(portId, mbufRxPtr);
    }
    ixOsalIrqUnlock(key);

    return status;
}

PRIVATE void
ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
				   IX_OSAL_MBUF * mBufPtr,
				   BOOL useMultiBufferCallback)
{
    /* call the callback which forwards the traffic to the client */
    ixEthAccPortDisableRx(portId, mBufPtr, useMultiBufferCallback);

    /* try to replenish with the buffer used in portDisable
     * if seen in Rx
     */
    ixEthAccPortDisableTryReplenish(portId);
}

PRIVATE void
ixEthAccPortDisableRxCallback (UINT32 cbTag,
			       IX_OSAL_MBUF * mBufPtr,
			       UINT32 learnedPortId)
{
    IxEthAccPortId portId = (IxEthAccPortId)cbTag;

    /* call the portDisable receive callback */
   (ixEthAccPortDisableRxTable[portId])(portId, mBufPtr, false);
}

PRIVATE void
ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
					  IX_OSAL_MBUF **mBufPtr)
{
    IxEthAccPortId portId = (IxEthAccPortId)cbTag;

    while (*mBufPtr)
    {
	/* call the portDisable receive callback with one buffer at a time */
	(ixEthAccPortDisableRxTable[portId])(portId, *mBufPtr++, true);
    }
}

IxEthAccStatus
ixEthAccPortDisablePriv(IxEthAccPortId portId)
{
    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
    int key;
    int retry, retryTimeout;
    volatile IxEthAccPortDisableState *state = &ixEthAccMacState[portId].portDisableState;
    volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
    volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable port.\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 the state is being set to what it is already at, do nothing */
    if (!ixEthAccMacState[portId].enabled)
    {
        return IX_ETH_ACC_SUCCESS;
    }

    *state = DISABLED;

    /* disable MAC receive first */
    ixEthAccPortRxDisablePriv(portId);

#ifdef CONFIG_IXP425_COMPONENT_ETHDB
    /* disable ethernet database for this port - It is done now to avoid
     * issuing ELT maintenance after requesting 'port disable' in an NPE
     */
    if (ixEthDBPortDisable(portId) != IX_ETH_DB_SUCCESS)
    {
	status = IX_ETH_ACC_FAIL;
        IX_ETH_ACC_FATAL_LOG("ixEthAccPortDisable: failed to disable EthDB for this port\n", 0, 0, 0, 0, 0, 0);
    }
#endif

    /* enter the critical section */
    key = ixOsalIrqLock();

    /* swap the Rx and TxDone callbacks */
    ixEthAccPortDisableFn[portId]            = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn;
    ixEthAccPortDisableMultiBufferFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn;
    ixEthAccPortDisableCbTag[portId]         = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag;
    ixEthAccPortDisableMultiBufferCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag;
    ixEthAccPortDisableTxDoneFn[portId]      = ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn;
    ixEthAccPortDisableTxDoneCbTag[portId]   = ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag;
    ixEthAccPortDisableRxTable[portId]       =  ixEthAccPortDisableRx;

    /* register temporary callbacks */
    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn            = ixEthAccPortDisableRxCallback;
    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag           = portId;

    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferRxCallback;
    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = portId;

    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn  = ixEthAccPortDisableTxDone;
    ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag           = portId;

    /* initialise the Rx state and Tx states */
    *txState = TRANSMIT_DONE;
    *rxState = RECEIVE;

    /* exit the critical section */
    ixOsalIrqUnlock(key);

    /* enable a NPE loopback */
    if (ixEthAccNpeLoopbackEnablePriv(portId) != IX_ETH_ACC_SUCCESS)
    {
	status = IX_ETH_ACC_FAIL;
    }

    if (status == IX_ETH_ACC_SUCCESS)
    {
	retry = 0;

	/* Step 1 : Drain Tx traffic and TxDone queues :
	 *
	 * Transmit and replenish at least once with the
	 * special buffers until both of them are seen
	 * in the callback hook
	 *
	 * (the receive callback keeps replenishing, so once we see
	 * the special Tx buffer, we can be sure that Tx drain is complete)
	 */
	ixEthAccPortDisableRxTable[portId]
	    =  ixEthAccPortDisableRxAndReplenish;
	ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
	    = ixEthAccPortDisableTxDone;

	do
	{
	    /* keep replenishing */
	    status = ixEthAccPortDisableTryReplenish(portId);
	    if (status == IX_ETH_ACC_SUCCESS)
	    {
		/* keep transmitting */
		status = ixEthAccPortDisableTryTransmit(portId);
	    }
	    if (status == IX_ETH_ACC_SUCCESS)
	    {
		/* wait for some traffic being processed */
		ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
	    }
	}
	while ((status == IX_ETH_ACC_SUCCESS)
	       && (retry++ < IX_ETH_ACC_MAX_RETRY)
	       && (*txState == TRANSMIT));

	/* Step 2 : Drain Rx traffic, RxFree and Rx queues :
	 *
	 * Transmit and replenish at least once with the
	 * special buffers until both of them are seen
	 * in the callback hook
	 * (the transmit callback keeps transmitting, and when we see
	 * the special Rx buffer, we can be sure that rxFree drain
	 * is complete)
	 *
	 * The nested loop helps to retry if the user was keeping
	 * replenishing or transmitting during portDisable.
	 *
	 * The 2 nested loops ensure more retries if user traffic is
	 * seen during portDisable : the user should not replenish
	 * or transmit while portDisable is running. However, because of
	 * the queueing possibilities in ethAcc dataplane, it is possible
	 * that a lot of traffic is left in the queues (e.g. when
	 * transmitting over a low speed link) and therefore, more
	 * retries are allowed to help flushing the buffers out.
	 */
	ixEthAccPortDisableRxTable[portId]
	    =  ixEthAccPortDisableRx;
	ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
	    = ixEthAccPortDisableTxDoneAndSubmit;

	do
	{
	    do
	    {
		ixEthAccPortDisableUserBufferCount[portId] = 0;

		/* keep replenishing */
		status = ixEthAccPortDisableTryReplenish(portId);
		if (status == IX_ETH_ACC_SUCCESS)
		{
		    /* keep transmitting */
		    status = ixEthAccPortDisableTryTransmit(portId);
		}
		if (status == IX_ETH_ACC_SUCCESS)
		{
		    /* wait for some traffic being processed */
		    ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
		}
	    }
	    while ((status == IX_ETH_ACC_SUCCESS)
		   && (retry++ < IX_ETH_ACC_MAX_RETRY)
		   && ((ixEthAccPortDisableUserBufferCount[portId] != 0)
		       || (*rxState == REPLENISH)));

	    /* After the first iteration, change the receive callbacks,
	     * to process only 1 buffer at a time
	     */
	    ixEthAccPortDisableRxTable[portId]
		= ixEthAccPortDisableRx;
	    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
		= ixEthAccPortDisableTxDone;

	    /* repeat the whole process while user traffic is seen in TxDone
	     *
	     * The conditions to stop the loop are
	     * - Xscale has both Rx and Tx special buffers
	     *   (txState = transmit, rxState = receive)
	     * - any error in txSubmit or rxReplenish
	     * - no user traffic seen
	     * - an excessive amount of retries
	     */
	}
	while ((status == IX_ETH_ACC_SUCCESS)
	       && (retry < IX_ETH_ACC_MAX_RETRY)
	       && (*txState == TRANSMIT));

	/* check the loop exit conditions. The NPE should not hold
	 * the special buffers.
	 */
	if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
	{
	    status = IX_ETH_ACC_FAIL;
	}

	if (status == IX_ETH_ACC_SUCCESS)
	{
	    /* Step 3 : Replenish without transmitting until a timeout
	     * occurs, in order to drain the internal NPE fifos
	     *
	     * we can expect a few frames srill held
	     * in the NPE.
	     *
	     * The 2 nested loops take care about the NPE dropping traffic
	     * (including loopback traffic) when the Rx queue is full.
	     *
	     * The timeout value is very conservative
	     * since the loopback used keeps replenishhing.
	     *
	     */
	    do
	    {
		ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRxAndReplenish;
		ixEthAccPortDisableUserBufferCount[portId] = 0;
		retryTimeout = 0;
		do
		{
		    /* keep replenishing */
		    status = ixEthAccPortDisableTryReplenish(portId);
		    if (status == IX_ETH_ACC_SUCCESS)
		    {
			/* wait for some traffic being processed */
			ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
		    }
		}
		while ((status == IX_ETH_ACC_SUCCESS)
		       && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));

		/* Step 4 : Transmit once. Stop replenish
		 *
		 * After the Rx timeout, we are sure that the NPE does not
		 * hold any frame in its internal NPE fifos.
		 *
		 * At this point, the NPE still holds the last rxFree buffer.
		 * By transmitting a single frame, this should unblock the
		 * last rxFree buffer. This code just transmit once and
		 * wait for both frames seen in TxDone and in rxFree.
		 *
		 */
		ixEthAccPortDisableRxTable[portId] =  ixEthAccPortDisableRx;
		status = ixEthAccPortDisableTryTransmit(portId);

		/* the NPE should immediatelyt release
		 * the last Rx buffer and the last transmitted buffer
		 * unless the last Tx frame was dropped (rx queue full)
		 */
		if (status == IX_ETH_ACC_SUCCESS)
		{
		    retryTimeout = 0;
		    do
		    {
			ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
		    }
		    while ((*rxState == REPLENISH)
			   && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));
		}

		/* the NPE may have dropped the traffic because of Rx
		 * queue being full. This code ensures that the last
		 * Tx and Rx frames are both received.
		 */
	    }
	    while ((status == IX_ETH_ACC_SUCCESS)
		   && (retry++ < IX_ETH_ACC_MAX_RETRY)
		   && ((*txState == TRANSMIT)
		       || (*rxState == REPLENISH)
		       || (ixEthAccPortDisableUserBufferCount[portId] != 0)));

	    /* Step 5 : check the final states : the NPE has
	     * no buffer left, nor in Tx , nor in Rx directions.
	     */
	    if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
	    {
		status = IX_ETH_ACC_FAIL;
	    }
	}

        /* now all the buffers are drained, disable NPE loopback
	 * This is done regardless of the logic to drain the queues and
	 * the internal buffers held by the NPE.
	 */
	if (ixEthAccNpeLoopbackDisablePriv(portId) != IX_ETH_ACC_SUCCESS)
	{
	    status = IX_ETH_ACC_FAIL;
	}
    }

    /* disable MAC Tx and Rx services */
    ixEthAccMacState[portId].enabled = false;
    ixEthAccMacStateUpdate(portId);

    /* restore the Rx and TxDone callbacks (within a critical section) */
    key = ixOsalIrqLock();

    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn            = ixEthAccPortDisableFn[portId];
    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag           = ixEthAccPortDisableCbTag[portId];
    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferFn[portId];
    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = ixEthAccPortDisableMultiBufferCbTag[portId];
    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn  = ixEthAccPortDisableTxDoneFn[portId];
    ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag           = ixEthAccPortDisableTxDoneCbTag[portId];

    ixOsalIrqUnlock(key);

    /* the MAC core rx/tx disable may left the MAC hardware in an
     * unpredictable state. A hw reset is executed before resetting
     * all the MAC parameters to a known value.
     */
    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_CORE_CNTRL,
	      IX_ETH_ACC_CORE_RESET);

    ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);

    /* rewrite all parameters to their current value */
    ixEthAccMacStateUpdate(portId);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_INT_CLK_THRESH,
	      IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_CORE_CNTRL,
	      IX_ETH_ACC_CORE_MDC_EN);

    return status;
}

IxEthAccStatus
ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled)
{
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);

        /* Since Eth NPE is not available, port must be disabled */
        *enabled = false ;
        return IX_ETH_ACC_SUCCESS ;
    }

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
        /* Since Eth NPE is not available, port must be disabled */
        *enabled = false ;
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }

    *enabled = ixEthAccMacState[portId].enabled;

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortMacResetPriv(IxEthAccPortId portId)
{
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reset Ethernet coprocessor.\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);
    }

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_CORE_CNTRL,
	      IX_ETH_ACC_CORE_RESET);

    ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);

    /* rewrite all parameters to their current value */
    ixEthAccMacStateUpdate(portId);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_INT_CLK_THRESH,
	      IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_CORE_CNTRL,
	      IX_ETH_ACC_CORE_MDC_EN);

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortLoopbackEnable(IxEthAccPortId portId)
{
    UINT32 regval;

    /* Turn off promiscuous mode */
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable loopback.\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);
    }

    /* read register */
    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_RX_CNTRL1,
	     regval);

    /* update register */
    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RX_CNTRL1,
	      regval | IX_ETH_ACC_RX_CNTRL1_LOOP_EN);

    return IX_ETH_ACC_SUCCESS;
}

PRIVATE void
ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
				    IxNpeMhMessage msg)
{
    IxEthAccPortId 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)
    {
	IX_ETH_ACC_FATAL_LOG("IXETHACC:ixEthAccPortDisableMessageCallback: Illegal port: %u\n",
            (UINT32) portId, 0, 0, 0, 0, 0);

	return;
    }
#endif

    /* unlock message reception mutex */
    ixOsalMutexUnlock(&ixEthAccMacState[portId].npeLoopbackMessageLock);
}

IxEthAccStatus
ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId)
{
    IX_STATUS npeMhStatus;
    IxNpeMhMessage message;
    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;

    /* Turn off promiscuous mode */
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\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);
    }

    /* enable NPE loopback (lsb of the message contains the value 1) */
    message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL)
	| 0x01;
    message.data[1] = 0;

    npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
		message,
		IX_ETHNPE_SETLOOPBACK_MODE_ACK,
		ixEthAccNpeLoopbackMessageCallback,
		IX_NPEMH_SEND_RETRIES_DEFAULT);

    if (npeMhStatus != IX_SUCCESS)
    {
        status = IX_ETH_ACC_FAIL;
    }
    else
    {
	/* wait for NPE loopbackEnable response */
        if (ixOsalMutexLock(&ixEthAccMacState[portId]. npeLoopbackMessageLock,
			    IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
	    != IX_SUCCESS)
        {
            status = IX_ETH_ACC_FAIL;
        }
    }

    return status;
}

IxEthAccStatus
ixEthAccPortTxEnablePriv(IxEthAccPortId portId)
{
    UINT32 regval;

    /* Turn off promiscuous mode */
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable TX.\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);
    }

    /* read register */
    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_TX_CNTRL1,
	     regval);

    /* update register */
    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_CNTRL1,
	      regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortRxEnablePriv(IxEthAccPortId portId)
{
    UINT32 regval;

    /* Turn off promiscuous mode */
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable RX.\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);
    }

    /* read register */
    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_RX_CNTRL1,
	     regval);

    /* update register */
    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RX_CNTRL1,
	      regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortLoopbackDisable(IxEthAccPortId portId)
{
    UINT32 regval;

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable loopback.\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);
    }

    /*disable MAC loopabck */
    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_RX_CNTRL1,
	     regval);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RX_CNTRL1,
	      (regval & ~IX_ETH_ACC_RX_CNTRL1_LOOP_EN));

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId)
{
    IX_STATUS npeMhStatus;
    IxNpeMhMessage message;
    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;

    /* Turn off promiscuous mode */
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\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);
    }

    /* disable NPE loopback (lsb of the message contains the value 0) */
    message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL);
    message.data[1] = 0;

    npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
		message,
		IX_ETHNPE_SETLOOPBACK_MODE_ACK,
		ixEthAccNpeLoopbackMessageCallback,
		IX_NPEMH_SEND_RETRIES_DEFAULT);

    if (npeMhStatus != IX_SUCCESS)
    {
        status = IX_ETH_ACC_FAIL;
    }
    else
    {
	/* wait for NPE loopbackEnable response */
        if (ixOsalMutexLock(&ixEthAccMacState[portId].npeLoopbackMessageLock,
			    IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
	    != IX_SUCCESS)
        {
            status = IX_ETH_ACC_FAIL;
        }
    }

    return status;
}

IxEthAccStatus
ixEthAccPortTxDisablePriv(IxEthAccPortId portId)
{
    UINT32 regval;

    /* Turn off promiscuous mode */
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable TX.\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);
    }

    /* read register */
    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_TX_CNTRL1,
	     regval);

    /* update register */
    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_CNTRL1,
	      (regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN));

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortRxDisablePriv(IxEthAccPortId portId)
{
    UINT32 regval;

    /* Turn off promiscuous mode */
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable RX.\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);
    }

    /* read register */
    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_RX_CNTRL1,
	     regval);

    /* update register */
    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RX_CNTRL1,
	      (regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN));

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId)
{
    UINT32 regval;

    /* Turn off promiscuous mode */
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear promiscuous mode.\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);
    }

    /*set bit 5 of Rx control 1 - enable address filtering*/
    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_RX_CNTRL1,
	     regval);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RX_CNTRL1,
	      regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);

    ixEthAccMacState[portId].promiscuous = false;

    ixEthAccMulticastAddressSet(portId);

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId)
{
    UINT32 regval;

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set promiscuous mode.\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);
    }

    /*
     * Set bit 5 of Rx control 1 - We enable address filtering even in
     * promiscuous mode because we want the MAC to set the appropriate
     * bits in m_flags which doesn't happen if we turn off filtering.
     */
    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_RX_CNTRL1,
	     regval);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RX_CNTRL1,
	      regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);

    ixEthAccMacState[portId].promiscuous = true;

    ixEthAccMulticastAddressSet(portId);

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId,
				  IxEthAccMacAddr *macAddr)
{
    UINT32 i;

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Unicast Mac Address.\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 (macAddr == NULL)
    {
	return IX_ETH_ACC_FAIL;
    }

    if ( macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT )
    {
	/* This is a multicast/broadcast address cant set it ! */
	return IX_ETH_ACC_FAIL;
    }

    if ( macAddr->macAddress[0] == 0 &&
	 macAddr->macAddress[1] == 0 &&
	 macAddr->macAddress[2] == 0 &&
	 macAddr->macAddress[3] == 0 &&
	 macAddr->macAddress[4] == 0 &&
	 macAddr->macAddress[5] == 0  )
    {
	/* This is an invalid mac address cant set it ! */
	return IX_ETH_ACC_FAIL;
    }

#ifdef CONFIG_IXP425_COMPONENT_ETHDB
    /* update the MAC address in the ethernet database */
    if (ixEthDBPortAddressSet(portId, (IxEthDBMacAddr *) macAddr) != IX_ETH_DB_SUCCESS)
    {
        return IX_ETH_ACC_FAIL;
    }
#endif

    /*Set the Unicast MAC to the specified value*/
    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
    {
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
		  macAddr->macAddress[i]);
    }
    ixEthAccMacState[portId].initDone = true;

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId,
				  IxEthAccMacAddr *macAddr)
{
    /*Return the current value of the Unicast MAC from h/w
      for the specified port*/
    UINT32 i;

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
        /* Since Eth Npe is unavailable, return invalid MAC Address = 00:00:00:00:00:00 */
        for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
        {
	    macAddr->macAddress[i] = 0;
        }
        return IX_ETH_ACC_SUCCESS ;
    }

    if(!ixEthAccMacState[portId].initDone)
    {
	return (IX_ETH_ACC_MAC_UNINITIALIZED);
    }

    if (macAddr == NULL)
    {
	return IX_ETH_ACC_FAIL;
    }


    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
    {
	REG_READ(ixEthAccMacBase[portId],
		 IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
		 macAddr->macAddress[i]);
    }
    return IX_ETH_ACC_SUCCESS;
}

PRIVATE IxEthAccStatus
ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
				    IxEthAccMacAddr *macAddr)
{
    /*Return the current value of the Multicast MAC from h/w
      for the specified port*/
    UINT32 i;

    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
    {

	REG_READ(ixEthAccMacBase[portId],
		 IX_ETH_ACC_MAC_ADDR_1 + i*sizeof(UINT32),
		 macAddr->macAddress[i]);
    }

    return IX_ETH_ACC_SUCCESS;
}

PRIVATE IxEthAccStatus
ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
				   IxEthAccMacAddr *macAddr)
{
    /*Return the current value of the Multicast MAC from h/w
      for the specified port*/
    UINT32 i;

    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
    {

	REG_READ(ixEthAccMacBase[portId],
		 IX_ETH_ACC_MAC_ADDR_MASK_1 + i*sizeof(UINT32),
		 macAddr->macAddress[i]);
    }
    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId,
				  IxEthAccMacAddr *macAddr)
{
    UINT32 i;
    IxEthAccMacAddr broadcastAddr = {{0xff,0xff,0xff,0xff,0xff,0xff}};

    /*Check that the port parameter is valid*/
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join Multicast Mac Address.\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 that the mac address is valid*/
    if(macAddr == NULL)
    {
	return IX_ETH_ACC_FAIL;
    }

    /* Check that this is a multicast address */
    if (!(macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT))
    {
	return IX_ETH_ACC_FAIL;
    }

    /* We don't add the Broadcast address */
    if(ixEthAccMacEqual(&broadcastAddr, macAddr))
    {
	return IX_ETH_ACC_FAIL;
    }

    for (i = 0;
	 i<ixEthAccMacState[portId].mcastAddrIndex;
	 i++)
    {
	/*Check if the current entry already match an existing matches*/
	if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i], macAddr))
	{
	    /* Address found in the list and already configured,
	     * return a success status
	     */
	    return IX_ETH_ACC_SUCCESS;
	}
    }

    /* check for availability at the end of the current table */
    if(ixEthAccMacState[portId].mcastAddrIndex >= IX_ETH_ACC_MAX_MULTICAST_ADDRESSES)
    {
	return IX_ETH_ACC_FAIL;
    }

    /*First add the address to the multicast table for the
      specified port*/
    i=ixEthAccMacState[portId].mcastAddrIndex;

    memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
	   &macAddr->macAddress,
	   IX_IEEE803_MAC_ADDRESS_SIZE);

    /*Increment the index into the table, this must be done here
     as MulticastAddressSet below needs to know about the latest
     entry.
    */
    ixEthAccMacState[portId].mcastAddrIndex++;

    /*Then calculate the new value to be written to the address and
      address mask registers*/
    ixEthAccMulticastAddressSet(portId);

    return IX_ETH_ACC_SUCCESS;
}


IxEthAccStatus
ixEthAccPortMulticastAddressJoinAllPriv (IxEthAccPortId portId)
{
    IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};

    /*Check that the port parameter is valid*/
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join all Multicast Address.\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);
    }

    /* remove all entries from the database and
    *  insert a multicast entry
    */
    memcpy(&ixEthAccMacState[portId].mcastAddrsTable[0],
	   &mcastMacAddr.macAddress,
	   IX_IEEE803_MAC_ADDRESS_SIZE);

    ixEthAccMacState[portId].mcastAddrIndex = 1;
    ixEthAccMacState[portId].joinAll = true;

    ixEthAccMulticastAddressSet(portId);

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId,
				   IxEthAccMacAddr *macAddr)
{
    UINT32 i;
    IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};

    /*Check that the port parameter is valid*/
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave Multicast Address.\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 that the mac address is valid*/
    if(macAddr == NULL)
    {
	return IX_ETH_ACC_FAIL;
    }
    /* Remove this mac address from the mask for the specified port
     * we copy down all entries above the blanked entry, and
     * decrement the index
     */
    i=0;

    while(i<ixEthAccMacState[portId].mcastAddrIndex)
    {
	/*Check if the current entry matches*/
	if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i],
			    macAddr))
	{
	    if(ixEthAccMacEqual(macAddr, &mcastMacAddr))
	    {
		ixEthAccMacState[portId].joinAll = false;
	    }
	    /*Decrement the index into the multicast address table
	      for the current port*/
	    ixEthAccMacState[portId].mcastAddrIndex--;

	    /*Copy down all entries above the current entry*/
	    while(i<ixEthAccMacState[portId].mcastAddrIndex)
	    {
		memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
		       &ixEthAccMacState[portId].mcastAddrsTable[i+1],
		       IX_IEEE803_MAC_ADDRESS_SIZE);
                i++;
	    }
	    /*recalculate the mask and write it to the MAC*/
	    ixEthAccMulticastAddressSet(portId);

	    return IX_ETH_ACC_SUCCESS;
	}
	/* search the next entry */
	i++;
    }
    /* no matching entry found */
    return IX_ETH_ACC_NO_SUCH_ADDR;
}

IxEthAccStatus
ixEthAccPortMulticastAddressLeaveAllPriv (IxEthAccPortId portId)
{
    /*Check that the port parameter is valid*/
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave all Multicast Address.\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);
    }

    ixEthAccMacState[portId].mcastAddrIndex = 0;
    ixEthAccMacState[portId].joinAll = false;

    ixEthAccMulticastAddressSet(portId);

    return IX_ETH_ACC_SUCCESS;
}


IxEthAccStatus
ixEthAccPortUnicastAddressShowPriv (IxEthAccPortId portId)
{
    IxEthAccMacAddr macAddr;

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Unicast Address.\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);
    }

    /*Get the MAC (UINICAST) address from hardware*/
    if(ixEthAccPortUnicastMacAddressGetPriv(portId, &macAddr) != IX_ETH_ACC_SUCCESS)
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: MAC address uninitialised port %u\n",
			       (INT32)portId,0,0,0,0,0);
	return IX_ETH_ACC_MAC_UNINITIALIZED;
    }

    /*print it out*/
    ixEthAccMacPrint(&macAddr);
    printf("\n");
    return IX_ETH_ACC_SUCCESS;
}



void
ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId)
{
    IxEthAccMacAddr macAddr;
    UINT32 i;

    if(!IX_ETH_ACC_IS_PORT_VALID(portId))
    {
        return;
    }

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Multicast Address.\n",(INT32)portId,0,0,0,0,0);
        return ;
    }

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

    printf("Multicast MAC: ");
    /*Get the MAC (MULTICAST) address from hardware*/
    ixEthAccPortMulticastMacAddressGet(portId, &macAddr);
    /*print it out*/
    ixEthAccMacPrint(&macAddr);
    /*Get the MAC (MULTICAST) filter from hardware*/
    ixEthAccPortMulticastMacFilterGet(portId, &macAddr);
    /*print it out*/
    printf(" ( ");
    ixEthAccMacPrint(&macAddr);
    printf(" )\n");
    printf("Constituent Addresses:\n");
    for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
    {
	ixEthAccMacPrint(&ixEthAccMacState[portId].mcastAddrsTable[i]);
	printf("\n");
    }
    return;
}

/*Set the duplex mode*/
IxEthAccStatus
ixEthAccPortDuplexModeSetPriv (IxEthAccPortId portId,
			   IxEthAccDuplexMode mode)
{
    UINT32 txregval;
    UINT32 rxregval;

    /*This is bit 1 of the transmit control reg, set to 1 for half
      duplex, 0 for full duplex*/
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Duplex Mode.\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);
    }

    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_TX_CNTRL1,
	     txregval);

    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_RX_CNTRL1,
	     rxregval);

    if (mode ==  IX_ETH_ACC_FULL_DUPLEX)
    {
	/*Clear half duplex bit in TX*/
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_TX_CNTRL1,
		  txregval & ~IX_ETH_ACC_TX_CNTRL1_DUPLEX);

	/*We must set the pause enable in the receive logic when in
	  full duplex mode*/
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_RX_CNTRL1,
		  rxregval | IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);
	ixEthAccMacState[portId].fullDuplex = true;

    }
    else if (mode ==  IX_ETH_ACC_HALF_DUPLEX)
    {
	/*Set half duplex bit in TX*/
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_TX_CNTRL1,
		  txregval | IX_ETH_ACC_TX_CNTRL1_DUPLEX);

	/*We must clear pause enable in the receive logic when in
	  half duplex mode*/
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_RX_CNTRL1,
		  rxregval & ~IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);

	ixEthAccMacState[portId].fullDuplex = false;
    }
    else
    {
	return IX_ETH_ACC_FAIL;
    }


    return IX_ETH_ACC_SUCCESS;

}



IxEthAccStatus
ixEthAccPortDuplexModeGetPriv (IxEthAccPortId portId,
			   IxEthAccDuplexMode *mode)
{
    /*Return the duplex mode for the specified port*/
    UINT32 regval;

    /*This is bit 1 of the transmit control reg, set to 1 for half
      duplex, 0 for full duplex*/
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Duplex Mode.\n",(INT32)portId,0,0,0,0,0);
        /* return hald duplex */
        *mode = IX_ETH_ACC_HALF_DUPLEX ;
        return IX_ETH_ACC_SUCCESS ;
    }

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

    if (mode == NULL)
    {
	return (IX_ETH_ACC_FAIL);
    }

    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_TX_CNTRL1,
	     regval);

    if( regval & IX_ETH_ACC_TX_CNTRL1_DUPLEX)
    {
	*mode = IX_ETH_ACC_HALF_DUPLEX;
    }
    else
    {
	*mode = IX_ETH_ACC_FULL_DUPLEX;
    }

    return IX_ETH_ACC_SUCCESS;
}



IxEthAccStatus
ixEthAccPortTxFrameAppendPaddingEnablePriv (IxEthAccPortId portId)
{
    UINT32 regval;
    /*Enable FCS computation by the MAC and appending to the
      frame*/

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append Padding.\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);
    }

    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_TX_CNTRL1,
	     regval);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_CNTRL1,
	      regval |
	      IX_ETH_ACC_TX_CNTRL1_PAD_EN);

    ixEthAccMacState[portId].txPADAppend = true;
    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortTxFrameAppendPaddingDisablePriv (IxEthAccPortId portId)
{
    UINT32 regval;

    /*disable FCS computation and appending*/
    /*Set bit 4 of Tx control register one to zero*/
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disble Tx Frame Append Padding.\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);
    }

    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_TX_CNTRL1,
	     regval);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_CNTRL1,
	      regval & ~IX_ETH_ACC_TX_CNTRL1_PAD_EN);

    ixEthAccMacState[portId].txPADAppend = false;
    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortTxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
{
    UINT32 regval;

    /*Enable FCS computation by the MAC and appending to the
      frame*/

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append FCS.\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);
    }

    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_TX_CNTRL1,
	     regval);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_CNTRL1,
	      regval | IX_ETH_ACC_TX_CNTRL1_FCS_EN);

    ixEthAccMacState[portId].txFCSAppend = true;
    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortTxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
{
    UINT32 regval;

    /*disable FCS computation and appending*/
    /*Set bit 4 of Tx control register one to zero*/
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Tx Frame Append FCS.\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);
    }

    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_TX_CNTRL1,
	     regval);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_TX_CNTRL1,
	      regval & ~IX_ETH_ACC_TX_CNTRL1_FCS_EN);

    ixEthAccMacState[portId].txFCSAppend = false;
    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortRxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
{
    /*Set bit 2 of Rx control 1*/
    UINT32 regval;

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Rx Frame Append FCS.\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);
    }

    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_RX_CNTRL1,
	     regval);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RX_CNTRL1,
	      regval | IX_ETH_ACC_RX_CNTRL1_CRC_EN);

    ixEthAccMacState[portId].rxFCSAppend = true;
    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccPortRxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
{
    UINT32 regval;

    /*Clear bit 2 of Rx control 1*/
    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Rx Frame Append FCS.\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);
    }

    REG_READ(ixEthAccMacBase[portId],
	     IX_ETH_ACC_MAC_RX_CNTRL1,
	     regval);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_RX_CNTRL1,
	      regval & ~IX_ETH_ACC_RX_CNTRL1_CRC_EN);

    ixEthAccMacState[portId].rxFCSAppend = false;
    return IX_ETH_ACC_SUCCESS;
}



PRIVATE void
ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
				    IxNpeMhMessage msg)
{
    IxEthAccPortId 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)
    {
	IX_ETH_ACC_FATAL_LOG(
     "IXETHACC:ixEthAccMacNpeStatsMessageCallback: Illegal port: %u\n",
     (UINT32)portId, 0, 0, 0, 0, 0);
	return;
    }
#endif

    /*Unblock Stats Get call*/
    ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsLock);

}

PRIVATE void
ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats *retStats)
{
    /* endianness conversion */

    /* Rx stats */
    retStats->dot3StatsAlignmentErrors =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsAlignmentErrors);
    retStats->dot3StatsFCSErrors =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsFCSErrors);
    retStats->dot3StatsInternalMacReceiveErrors =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacReceiveErrors);
    retStats->RxOverrunDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxOverrunDiscards);
    retStats->RxLearnedEntryDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLearnedEntryDiscards);
    retStats->RxLargeFramesDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLargeFramesDiscards);
    retStats->RxSTPBlockedDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxSTPBlockedDiscards);
    retStats->RxVLANTypeFilterDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANTypeFilterDiscards);
    retStats->RxVLANIdFilterDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANIdFilterDiscards);
    retStats->RxInvalidSourceDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxInvalidSourceDiscards);
    retStats->RxBlackListDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxBlackListDiscards);
    retStats->RxWhiteListDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxWhiteListDiscards);
    retStats->RxUnderflowEntryDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxUnderflowEntryDiscards);

    /* Tx stats */
    retStats->dot3StatsSingleCollisionFrames =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsSingleCollisionFrames);
    retStats->dot3StatsMultipleCollisionFrames =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsMultipleCollisionFrames);
    retStats->dot3StatsDeferredTransmissions =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsDeferredTransmissions);
    retStats->dot3StatsLateCollisions =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsLateCollisions);
    retStats->dot3StatsExcessiveCollsions =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsExcessiveCollsions);
    retStats->dot3StatsInternalMacTransmitErrors =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacTransmitErrors);
    retStats->dot3StatsCarrierSenseErrors =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsCarrierSenseErrors);
    retStats->TxLargeFrameDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxLargeFrameDiscards);
    retStats->TxVLANIdFilterDiscards =
	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxVLANIdFilterDiscards);
}

IxEthAccStatus
ixEthAccMibIIStatsGet (IxEthAccPortId portId,
		       IxEthEthObjStats *retStats )
{
    IxNpeMhMessage message;

    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
        printf("EthAcc: ixEthAccMibIIStatsGet (Mac) EthAcc service is not initialized\n");
	return (IX_ETH_ACC_FAIL);
    }

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (retStats == NULL)
    {
        printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NULL argument\n");
	return (IX_ETH_ACC_FAIL);
    }

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NPE for port %d is not available\n", portId);

        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get MIB II Stats.\n",(INT32)portId,0,0,0,0,0);

        /* Return all zero stats */
        IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));

        return IX_ETH_ACC_SUCCESS ;
    }

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
        printf("EthAcc: ixEthAccMibIIStatsGet (Mac) port %d is not initialized\n", portId);
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }

    IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));

    message.data[0] = IX_ETHNPE_GETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
    message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);

    /* Permit only one task to request MIB statistics Get operation
       at a time */
    ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetAccessLock, IX_OSAL_WAIT_FOREVER);

    if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
				      message,
				      IX_ETHNPE_GETSTATS,
				      ixEthAccMacNpeStatsMessageCallback,
				      IX_NPEMH_SEND_RETRIES_DEFAULT)
       != IX_SUCCESS)
    {
	ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);

        printf("EthAcc: (Mac) StatsGet failed to send NPE message\n");

	return IX_ETH_ACC_FAIL;
    }

    /* Wait for callback invocation indicating response to
       this request - we need this mutex in order to ensure
       that the return from this function is synchronous */
    ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);

    /* Permit other tasks to perform MIB statistics Get operation */
    ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);

    ixEthAccMibIIStatsEndianConvert (retStats);

    return IX_ETH_ACC_SUCCESS;
}


PRIVATE void
ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
					 IxNpeMhMessage msg)
{
    IxEthAccPortId 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)
    {
	IX_ETH_ACC_FATAL_LOG(
     "IXETHACC:ixEthAccMacNpeStatsResetMessageCallback: Illegal port: %u\n",
     (UINT32)portId, 0, 0, 0, 0, 0);
	return;
    }
#endif

    /*Unblock Stats Get & reset call*/
    ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsResetLock);

}



IxEthAccStatus
ixEthAccMibIIStatsGetClear (IxEthAccPortId portId,
			    IxEthEthObjStats *retStats)
{
    IxNpeMhMessage message;

    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
        printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) EthAcc service is not initialized\n");
	return (IX_ETH_ACC_FAIL);
    }

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (retStats == NULL)
    {
        printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NULL argument\n");
	return (IX_ETH_ACC_FAIL);
    }

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NPE for port %d is not available\n", portId);

        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get and clear MIB II Stats.\n", (INT32)portId, 0, 0, 0, 0, 0);

        /* Return all zero stats */
        IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));

        return IX_ETH_ACC_SUCCESS ;
    }

    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
    {
        printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) port %d is not initialized\n", portId);
	return (IX_ETH_ACC_PORT_UNINITIALIZED);
    }

    IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));

    message.data[0] = IX_ETHNPE_RESETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
    message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);

    /* Permit only one task to request MIB statistics Get-Reset operation at a time */
    ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock, IX_OSAL_WAIT_FOREVER);

    if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
				      message,
				      IX_ETHNPE_RESETSTATS,
				      ixEthAccMacNpeStatsResetMessageCallback,
				      IX_NPEMH_SEND_RETRIES_DEFAULT)
       != IX_SUCCESS)
    {
	ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);

        printf("EthAcc: (Mac) ixEthAccMibIIStatsGetClear failed to send NPE message\n");

	return IX_ETH_ACC_FAIL;
    }

    /* Wait for callback invocation indicating response to this request */
    ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);

    /* permit other tasks to get and reset MIB stats*/
    ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);

    ixEthAccMibIIStatsEndianConvert(retStats);

    return IX_ETH_ACC_SUCCESS;
}

IxEthAccStatus
ixEthAccMibIIStatsClear (IxEthAccPortId portId)
{
    static IxEthEthObjStats retStats;
    IxEthAccStatus status;

    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
	return (IX_ETH_ACC_FAIL);
    }

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear MIB II Stats.\n",(INT32)portId,0,0,0,0,0);
        return IX_ETH_ACC_SUCCESS ;
    }

    /* there is no reset operation without a corresponding Get */
    status = ixEthAccMibIIStatsGetClear(portId, &retStats);

    return status;
}

/* Initialize the ethernet MAC settings */
IxEthAccStatus
ixEthAccMacInit(IxEthAccPortId portId)
{
    IX_OSAL_MBUF_POOL* portDisablePool;
    UINT8 *data;

    IX_ETH_ACC_VALIDATE_PORT_ID(portId);

    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
    {
        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Mac.\n",(INT32)portId,0,0,0,0,0);
        return IX_ETH_ACC_SUCCESS ;
    }

    if(ixEthAccMacState[portId].macInitialised == false)
    {
	ixEthAccMacState[portId].fullDuplex  = true;
	ixEthAccMacState[portId].rxFCSAppend = true;
	ixEthAccMacState[portId].txFCSAppend = true;
	ixEthAccMacState[portId].txPADAppend = true;
	ixEthAccMacState[portId].enabled     = false;
	ixEthAccMacState[portId].promiscuous = true;
	ixEthAccMacState[portId].joinAll     = false;
	ixEthAccMacState[portId].initDone    = false;
	ixEthAccMacState[portId].macInitialised = true;

        /* initialize MIB stats mutexes */
        ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsLock);
        ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_OSAL_WAIT_FOREVER);

        ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsResetLock);
        ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_OSAL_WAIT_FOREVER);

        ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetAccessLock);

        ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);

        ixOsalMutexInit(&ixEthAccMacState[portId].npeLoopbackMessageLock);

	ixEthAccMacState[portId].portDisableRxMbufPtr = NULL;
        ixEthAccMacState[portId].portDisableTxMbufPtr = NULL;

	portDisablePool = IX_OSAL_MBUF_POOL_INIT(2,
			  IX_ETHACC_RX_MBUF_MIN_SIZE,
			  "portDisable Pool");

        IX_OSAL_ENSURE(portDisablePool != NULL, "Failed to initialize PortDisable pool");

	ixEthAccMacState[portId].portDisableRxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);
        ixEthAccMacState[portId].portDisableTxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);

	IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableRxMbufPtr != NULL,
		  "Pool allocation failed");
        IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableTxMbufPtr != NULL,
		  "Pool allocation failed");
	/* fill the payload of the Rx mbuf used in portDisable */
        IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableRxMbufPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;

        memset(IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableRxMbufPtr),
	       0xAA,
	       IX_ETHACC_RX_MBUF_MIN_SIZE);

	/* fill the payload of the Tx mbuf used in portDisable (64 bytes) */
        IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;
        IX_OSAL_MBUF_PKT_LEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;

        data = (UINT8 *) IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableTxMbufPtr);
        memset(data, 0xBB, 64);
        data[0] = 0x00; /* unicast destination MAC address */
        data[6] = 0x00; /* unicast source MAC address */
        data[12] = 0x08; /* typelength : IP frame */
        data[13] = 0x00; /* typelength : IP frame */

	IX_OSAL_CACHE_FLUSH(data, 64);
    }

    IX_OSAL_ASSERT (ixEthAccMacBase[portId] != 0);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_CORE_CNTRL,
	      IX_ETH_ACC_CORE_RESET);

    ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_CORE_CNTRL,
	      IX_ETH_ACC_CORE_MDC_EN);

    REG_WRITE(ixEthAccMacBase[portId],
	      IX_ETH_ACC_MAC_INT_CLK_THRESH,
	      IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);

    ixEthAccMacStateUpdate(portId);

    return IX_ETH_ACC_SUCCESS;
}

/* PRIVATE Functions*/

PRIVATE void
ixEthAccMacStateUpdate(IxEthAccPortId portId)
{
    UINT32 regval;

    if ( ixEthAccMacState[portId].enabled == false )
    {
	/*  Just disable both the transmitter and reciver in the MAC.  */
        REG_READ(ixEthAccMacBase[portId],
		 IX_ETH_ACC_MAC_RX_CNTRL1,
		 regval);
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_RX_CNTRL1,
		  regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN);

        REG_READ(ixEthAccMacBase[portId],
		 IX_ETH_ACC_MAC_TX_CNTRL1,
		 regval);
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_TX_CNTRL1,
		  regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN);
    }

    if(ixEthAccMacState[portId].fullDuplex)
    {
	ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_FULL_DUPLEX);
    }
    else
    {
	ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_HALF_DUPLEX);
    }

    if(ixEthAccMacState[portId].rxFCSAppend)
    {
	ixEthAccPortRxFrameAppendFCSEnablePriv (portId);
    }
    else
    {
	ixEthAccPortRxFrameAppendFCSDisablePriv (portId);
    }

    if(ixEthAccMacState[portId].txFCSAppend)
    {
	ixEthAccPortTxFrameAppendFCSEnablePriv (portId);
    }
    else
    {
	ixEthAccPortTxFrameAppendFCSDisablePriv (portId);
    }

    if(ixEthAccMacState[portId].txPADAppend)
    {
	ixEthAccPortTxFrameAppendPaddingEnablePriv (portId);
    }
    else
    {
	ixEthAccPortTxFrameAppendPaddingDisablePriv (portId);
    }

    if(ixEthAccMacState[portId].promiscuous)
    {
	ixEthAccPortPromiscuousModeSetPriv(portId);
    }
    else
    {
	ixEthAccPortPromiscuousModeClearPriv(portId);
    }

    if ( ixEthAccMacState[portId].enabled == true )
    {
        /*   Enable both the transmitter and reciver in the MAC.  */
        REG_READ(ixEthAccMacBase[portId],
		 IX_ETH_ACC_MAC_RX_CNTRL1,
		 regval);
        REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_RX_CNTRL1,
		  regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);

        REG_READ(ixEthAccMacBase[portId],
		 IX_ETH_ACC_MAC_TX_CNTRL1,
		 regval);
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_TX_CNTRL1,
		  regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);
    }
}


PRIVATE BOOL
ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
		 IxEthAccMacAddr *macAddr2)
{
    UINT32 i;
    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE; i++)
    {
	if(macAddr1->macAddress[i] != macAddr2->macAddress[i])
	{
	    return false;
	}
    }
    return true;
}

PRIVATE void
ixEthAccMacPrint(IxEthAccMacAddr *m)
{
    printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
	   m->macAddress[0], m->macAddress[1],
	   m->macAddress[2], m->macAddress[3],
	   m->macAddress[4], m->macAddress[5]);
}

/* Set the multicast address and address mask registers
 *
 * A bit in the address mask register must be set if
 * all multicast addresses always have that bit set, or if
 * all multicast addresses always have that bit cleared.
 *
 * A bit in the address register must be set if all multicast
 * addresses have that bit set, otherwise, it should be cleared
 */

PRIVATE void
ixEthAccMulticastAddressSet(IxEthAccPortId portId)
{
    UINT32 i;
    UINT32 j;
    IxEthAccMacAddr addressMask;
    IxEthAccMacAddr address;
    IxEthAccMacAddr alwaysClearBits;
    IxEthAccMacAddr alwaysSetBits;

    /* calculate alwaysClearBits and alwaysSetBits:
     * alwaysClearBits is calculated by ORing all
     * multicast addresses, those bits that are always
     * clear are clear in the result
     *
     * alwaysSetBits is calculated by ANDing all
     * multicast addresses, those bits that are always set
     * are set in the result
     */

    if (ixEthAccMacState[portId].promiscuous == true)
    {
	/* Promiscuous Mode is set, and filtering
	 * allow all packets, and enable the mcast and
	 * bcast detection.
	 */
	memset(&addressMask.macAddress,
	       0,
	       IX_IEEE803_MAC_ADDRESS_SIZE);
	memset(&address.macAddress,
	       0,
	       IX_IEEE803_MAC_ADDRESS_SIZE);
    }
    else
    {
	if(ixEthAccMacState[portId].joinAll == true)
	{
	    /* Join all is set. The mask and address are
	     * the multicast settings.
	     */
	    IxEthAccMacAddr macAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};

	    memcpy(addressMask.macAddress,
		   macAddr.macAddress,
		   IX_IEEE803_MAC_ADDRESS_SIZE);
	    memcpy(address.macAddress,
		   macAddr.macAddress,
		   IX_IEEE803_MAC_ADDRESS_SIZE);
	}
	else if(ixEthAccMacState[portId].mcastAddrIndex == 0)
	{
	    /* No entry in the filtering database,
	     * Promiscuous Mode is cleared, Broadcast filtering
	     * is configured.
	     */
	    memset(addressMask.macAddress,
		   IX_ETH_ACC_MAC_ALL_BITS_SET,
		   IX_IEEE803_MAC_ADDRESS_SIZE);
	    memset(address.macAddress,
		   IX_ETH_ACC_MAC_ALL_BITS_SET,
		   IX_IEEE803_MAC_ADDRESS_SIZE);
	}
	else
	{
	    /* build a mask and an address which mix all entreis
	     * from the list of multicast addresses
	     */
	    memset(alwaysClearBits.macAddress,
		   0,
		   IX_IEEE803_MAC_ADDRESS_SIZE);
	    memset(alwaysSetBits.macAddress,
		   IX_ETH_ACC_MAC_ALL_BITS_SET,
		   IX_IEEE803_MAC_ADDRESS_SIZE);

	    for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
	    {
		for(j=0;j<IX_IEEE803_MAC_ADDRESS_SIZE;j++)
		{
		    alwaysClearBits.macAddress[j] |=
			ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
		    alwaysSetBits.macAddress[j] &=
			ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
		}
	    }

	    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
	    {
		addressMask.macAddress[i] = alwaysSetBits.macAddress[i]
		    | ~alwaysClearBits.macAddress[i];
		address.macAddress[i] = alwaysSetBits.macAddress[i];
	    }
	}
    }

    /*write the new addr filtering to h/w*/
    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
    {
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_ADDR_MASK_1+i*sizeof(UINT32),
		  addressMask.macAddress[i]);
	REG_WRITE(ixEthAccMacBase[portId],
		  IX_ETH_ACC_MAC_ADDR_1+i*sizeof(UINT32),
		  address.macAddress[i]);
    }
}
