⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ixethaccmac.c

📁 AMCC POWERPC 44X系列的U-BOOT文件
💻 C
📖 第 1 页 / 共 5 页
字号:
/** * @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 * 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 "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 voidixEthAccPortDisableRx (IxEthAccPortId portId,		       IX_OSAL_MBUF * mBufPtr,		       BOOL useMultiBufferCallback);PRIVATE voidixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,				   IX_OSAL_MBUF * mBufPtr,				   BOOL useMultiBufferCallback);PRIVATE voidixEthAccPortDisableTxDone (UINT32 cbTag,			   IX_OSAL_MBUF *mbuf);PRIVATE voidixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag,				    IX_OSAL_MBUF *mbuf);PRIVATE voidixEthAccPortDisableRxCallback (UINT32 cbTag,			       IX_OSAL_MBUF * mBufPtr,			       UINT32 learnedPortId);PRIVATE voidixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,					  IX_OSAL_MBUF **mBufPtr);PRIVATE IxEthAccStatusixEthAccPortDisableTryTransmit(UINT32 portId);PRIVATE IxEthAccStatusixEthAccPortDisableTryReplenish(UINT32 portId);PRIVATE IxEthAccStatusixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,				    IxEthAccMacAddr *macAddr);PRIVATE IxEthAccStatusixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,				   IxEthAccMacAddr *macAddr);PRIVATE voidixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,				    IxNpeMhMessage msg);PRIVATE voidixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,					 IxNpeMhMessage msg);PRIVATE voidixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,				    IxNpeMhMessage msg);PRIVATE voidixEthAccMulticastAddressSet(IxEthAccPortId portId);PRIVATE BOOLixEthAccMacEqual(IxEthAccMacAddr *macAddr1,		 IxEthAccMacAddr *macAddr2);PRIVATE voidixEthAccMacPrint(IxEthAccMacAddr *m);PRIVATE voidixEthAccMacStateUpdate(IxEthAccPortId portId);IxEthAccStatusixEthAccMacMemInit(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;}voidixEthAccMacUnload(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;}IxEthAccStatusixEthAccPortEnablePriv(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 IxEthAccPortRxCallbackixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS];static IxEthAccPortMultiBufferRxCallbackixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS];static IxEthAccPortDisableRxixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS];static UINT32ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];static UINT32ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];static IxEthAccPortTxDoneCallbackixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS];static UINT32ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];static UINT32ixEthAccPortDisableUserBufferCount[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 voidixEthAccPortDisableTxDone(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 IxEthAccStatusixEthAccPortDisableTryTransmit(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 voidixEthAccPortDisableTxDoneAndSubmit(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 voidixEthAccPortDisableRx (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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -