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

📄 ixethacccommon.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * @file IxEthAccCommon.c * * @author Intel Corporation * @date 12-Feb-2002 * * @brief This file contains the implementation common support routines for the component * * Design Notes: * * @par  * IXP400 SW Release version 2.1 *  * -- Copyright Notice -- *  * @par * Copyright (c) 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 -- *//*  * Component header files  */#include "IxOsal.h"#include "IxEthAcc.h"#include "IxEthDB.h"#include "IxNpeMh.h"#include "IxEthDBPortDefs.h"#include "IxFeatureCtrl.h"#include "IxEthAcc_p.h"#include "IxEthAccQueueAssign_p.h"#include "IxEthAccDataPlane_p.h"#include "IxEthAccMii_p.h"#include "IxNpeDl.h"	/** * @addtogroup IxEthAccPri *@{ */extern IxEthAccInfo   ixEthAccDataInfo;/** * @brief Stores Rx Queue info for all rx queues */IX_ETH_ACC_PRIVATEIxEthAccRxQueue ixEthAccRxQueues[IX_ETHACC_MAX_RX_QUEUES+1];/* storage for the qmgr register base addresses */UINT32 ixEthAccQMIntEnableBaseAddress;UINT32 ixEthAccQMIntStatusBaseAddress;/** * * @brief Data structure template for RX Queues * */IX_ETH_ACC_PRIVATEIxEthAccQregInfo ixEthAccQmgrRxTemplate ={     IX_QMGR_QUEUE_INVALID, 	     /**< Queue ID */    "Eth Rx Q",     ixEthRxFrameQMCallback,          /**< Functional callback */    (IxQMgrCallbackId) 0,	     /**< Callback tag	      */     IX_QMGR_Q_SIZE128,		     /**< Allocate Max Size Q */    IX_QMGR_Q_ENTRY_SIZE1,	     /**< Queue Entry Sizes - all Q entries are single word entries   */    TRUE,			     /**< Enable Q notification at startup */    IX_QMGR_Q_SOURCE_ID_NOT_E,	     /**< Q Condition to drive callback   */    IX_QMGR_Q_WM_LEVEL0, 	     /**< Q Low water mark */    IX_QMGR_Q_WM_LEVEL1,	     /**< Q High water mark - needed by NPE */};/** * * @brief Data structure template for RX Free Queues * */IX_ETH_ACC_PRIVATEIxEthAccQregInfo ixEthAccQmgrRxFreeTemplate ={    IX_QMGR_QUEUE_INVALID,    "Eth Rx Free Q",    ixEthRxFreeQMCallback,    (IxQMgrCallbackId) 0,    IX_QMGR_Q_SIZE128,               /**< Allocate Max Size Q */    IX_QMGR_Q_ENTRY_SIZE1,           /**< Queue Entry Sizes - all Q entries are single word entries   */    FALSE,                           /**< Disable Q notification at startup */    IX_QMGR_Q_SOURCE_ID_E,	     /**< Q Condition to drive callback  */    IX_QMGR_Q_WM_LEVEL0,             /***< Q Low water mark */    IX_QMGR_Q_WM_LEVEL64,            /**< Q High water mark */};/** * * @brief Data structure template for TX Queues * */IX_ETH_ACC_PRIVATEIxEthAccQregInfo ixEthAccQmgrTxTemplate ={     IX_QMGR_QUEUE_INVALID,    "Eth Tx Q",     ixEthTxFrameQMCallback,     (IxQMgrCallbackId) 0,    IX_QMGR_Q_SIZE128,               /**< Allocate Max Size Q */    IX_QMGR_Q_ENTRY_SIZE1,           /**< Queue Entry Sizes - all Q entries are single word entries   */    FALSE,                           /**< Disable Q notification at startup */    IX_QMGR_Q_SOURCE_ID_E,	     /**< Q Condition to drive callback  */    IX_QMGR_Q_WM_LEVEL0,             /**< Q Low water mark */    IX_QMGR_Q_WM_LEVEL64,            /**< Q High water mark */};/** * * @brief Data structure template for TxDone Queue * */IX_ETH_ACC_PRIVATEIxEthAccQregInfo ixEthAccQmgrTxDoneTemplate ={     IX_ETH_ACC_TX_DONE_Q,    "Eth Tx Done Q",     ixEthTxFrameDoneQMCallback,     (IxQMgrCallbackId) 0,    IX_QMGR_Q_SIZE128,               /**< Allocate Max Size Q */    IX_QMGR_Q_ENTRY_SIZE1,           /**< Queue Entry Sizes - all Q entries are single word entries   */    TRUE,                            /**< Enable Q notification at startup */    IX_QMGR_Q_SOURCE_ID_NOT_E,	     /**< Q Condition to drive callback  */    IX_QMGR_Q_WM_LEVEL0,             /**< Q Low water mark */    IX_QMGR_Q_WM_LEVEL2,             /**< Q High water mark - needed by NPE */};/** * @brief RX Queue size table indexed by relative queue priority */IX_ETH_ACC_PRIVATE constIxQMgrQSizeInWords ixEthAccRxQueueSizeTable[IX_ETHACC_MAX_RX_QUEUES] ={    IX_QMGR_Q_SIZE128, /* highest priority */    IX_QMGR_Q_SIZE64,  /* second highest */    IX_QMGR_Q_SIZE32,  /* third highest */    IX_QMGR_Q_SIZE16,  /* fourth highest */    IX_QMGR_Q_SIZE16,  /* fifth highest */    IX_QMGR_Q_SIZE16,  /* sixth highest */    IX_QMGR_Q_SIZE16,  /* seventh highest */    IX_QMGR_Q_SIZE16   /* lowest */};/** * @brief Queue nearly full watermark table indexed by NPE count */IX_ETH_ACC_PRIVATE constIxQMgrWMLevel ixEthAccQueueNFWatermarkTable[] ={    IX_QMGR_Q_WM_LEVEL0,  /* NPE count == 0 (invalid) */     IX_QMGR_Q_WM_LEVEL0,  /* NPE count == 1 */    IX_QMGR_Q_WM_LEVEL1,  /* NPE count == 2 */    IX_QMGR_Q_WM_LEVEL2,  /* NPE count == 3 */    IX_QMGR_Q_WM_LEVEL4,  /* NPE count == 4 */    IX_QMGR_Q_WM_LEVEL4,  /* NPE count == 5 */    IX_QMGR_Q_WM_LEVEL8,  /* NPE count == 6 */    IX_QMGR_Q_WM_LEVEL8   /* NPE count == 7 */};/** * @brief Static Queue assignment array per NPEs indexed by NPE ID */IX_ETH_ACC_PRIVATE constUINT8 ixEthAccNpeStaticQueueConfigs[][2] ={    /* { TX Queue              , RX Free Queue } */    { IX_ETH_ACC_TX_NPEA_Q, IX_ETH_ACC_RX_FREE_NPEA_Q},    { IX_ETH_ACC_TX_NPEB_Q, IX_ETH_ACC_RX_FREE_NPEB_Q},    { IX_ETH_ACC_TX_NPEC_Q, IX_ETH_ACC_RX_FREE_NPEC_Q}};/** * @fn ixEthAccQMgrQueueSetup(IxEthAccQregInfo*) * * @brief Setup one queue and its event, and register the callback required  * by this component to the QMgr * * @internal */IX_ETH_ACC_PRIVATE IxEthAccStatus ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes){    int ret;    ret = ixQMgrQConfig( qInfoDes->qName,			qInfoDes->qId,			qInfoDes->qSize,			qInfoDes->qWords);    /* If queue is already configured, continue anyway */    if(ret != IX_SUCCESS && ret != IX_QMGR_Q_ALREADY_CONFIGURED)    {	return IX_ETH_ACC_FAIL;    }	    if ( ixQMgrWatermarkSet( qInfoDes->qId,			     qInfoDes->AlmostEmptyThreshold,			     qInfoDes->AlmostFullThreshold			     ) != IX_SUCCESS)    {	return IX_ETH_ACC_FAIL;    }    /*      * Set dispatcher priority.      */    if ( ixQMgrDispatcherPrioritySet( qInfoDes->qId, 				      IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY) 	 != IX_SUCCESS)    {	return IX_ETH_ACC_FAIL;    }	    /*     * Register callbacks for each Q.     */     if ( ixQMgrNotificationCallbackSet(qInfoDes->qId,				       qInfoDes->qCallback,				       qInfoDes->callbackTag) 	 != IX_SUCCESS )    {	return IX_ETH_ACC_FAIL;    }    /*     * Set notification condition for Q     */      if ( qInfoDes->qNotificationEnableAtStartup == TRUE )     {	if (   ixQMgrNotificationEnable(qInfoDes->qId,					qInfoDes->qConditionSource)	       != IX_SUCCESS )	{	    return IX_ETH_ACC_FAIL;	}    }    return(IX_ETH_ACC_SUCCESS);}/* * ixEthAccQMgrQueueUnsetup () * added to the same file */PRIVATE IxEthAccStatusixEthAccQMgrQueueUnsetup (IxEthAccQregInfo *qInfoDes){    if (IX_ETH_ACC_SUCCESS != ixQMgrNotificationDisable(qInfoDes->qId))    {        IX_ETH_ACC_WARNING_LOG ("Failed to disable the notification\n", 0, 0, 0, 0, 0, 0);        return IX_ETH_ACC_FAIL;    }    return IX_ETH_ACC_SUCCESS;}/** * @fn ixEthAccGetRxQueueList(IxEthAccPortId, IxEthAccRxQueue *) * * @brief Fill in and sort the rx queue array  * * @li select all Rx queues as configured by ethDB for all ports * @li sort the queues by traffic class * * @param none * * @return UINT32 (num Rx queues) * * @internal */IX_ETH_ACC_PRIVATEIxEthAccStatus ixEthAccGetRxQueueList(IxEthAccPortId portId, IxEthAccRxQueue *rxQueues){    IxEthDBStatus ixEthDBStatus = IX_ETH_DB_SUCCESS;    IxEthDBProperty ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;    IxEthDBPropertyType ixEthDBPropertyType = IX_ETH_DB_INTEGER_PROPERTY;    UINT32 ixEthDBParameter = 0;    BOOL completelySorted = FALSE;    UINT32 rxQueue = 0;    UINT32 sortIterations = 0;    IxEthNpeNodeId ixNpeId = IX_ETHNPE_PHYSICAL_ID_TO_NODE(portId);    /*      * Queue Selection step:     *     * The following code selects all the queues and fills     * the RxQueue array     *     */    /* Iterate thru the different priorities */    for (ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; 	 ixEthDBTrafficClass <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY; 	 ixEthDBTrafficClass++)    {	ixEthDBStatus = ixEthDBFeaturePropertyGet(				portId,				IX_ETH_DB_VLAN_QOS,				ixEthDBTrafficClass,				&ixEthDBPropertyType,				(void *)&ixEthDBParameter);	if (ixEthDBStatus == IX_ETH_DB_SUCCESS)	{	    /* This port and QoS class are mapped to 	     * a RX queue.	     */	    if (ixEthDBPropertyType == IX_ETH_DB_INTEGER_PROPERTY)	    {		/* search the queue in the list of queues		 * already used by an other port or QoS		 */		for (	rxQueue = 0;			((rxQueues[rxQueue].npeCount != 0)			&& (rxQueue < IX_ETHACC_MAX_RX_QUEUES));			rxQueue++)		{		    if (rxQueues[rxQueue].qId == (IxQMgrQId)ixEthDBParameter)		    {			/* found an existing setup, update the number of ports 			 * for this queue if the port maps to			 * a different NPE.			 */			if (rxQueues[rxQueue].npeId != ixNpeId)			{			    rxQueues[rxQueue].npeCount++;			    rxQueues[rxQueue].npeId = ixNpeId;			}			/* get the highest traffic class for this queue */			if (rxQueues[rxQueue].trafficClass > ixEthDBTrafficClass)			{			    rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass;			}			break;		    }		}		if (rxQueues[rxQueue].npeCount == 0)		{		    /* new queue not found in the current list, 		     * add a new entry.		     */		    IX_OSAL_ASSERT(rxQueue < IX_ETHACC_MAX_RX_QUEUES);		    rxQueues[rxQueue].qId = ixEthDBParameter;		    rxQueues[rxQueue].npeCount = 1;		    rxQueues[rxQueue].npeId = ixNpeId;		    rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass;		}	    }	    else	    {		/* unexpected property type (not Integer) */                IX_ETH_ACC_WARNING_LOG("ixEthAccGetRxQueueList: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0);		/* no point to continue to iterate */		return (IX_ETH_ACC_FAIL);	    }	}	else	{	    /* No Rx queue configured for this port	     * and this traffic class. Do nothing.	     */	}    }    /* check there is at least 1 rx queue : there is no point     * to continue if there is no rx queue configured      */    if (rxQueues[0].npeCount == 0)    {        IX_ETH_ACC_WARNING_LOG("ixEthAccGetRxQueueList: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0);	/* queue configuration error so return queue count 0 */	return (IX_ETH_ACC_FAIL);    }    /* Queue sort step:     *     * Re-order the array of queues by decreasing traffic class     * using a bubble sort. (trafficClass 0 is the lowest      * priority traffic, trafficClass 7 is the highest priority traffic)     *     * Primary sort order is traffic class     * Secondary sort order is npeId     *     * Note that a bubble sort algorithm is not very efficient when     * the number of queues grows . However, this is not a very bad choice      * considering the very small number of entries to sort. Also, bubble     * sort is extremely fast when the list is already sorted.     *     * The output of this loop is a sorted array of queues.     *     */    sortIterations = 0;    do    {	sortIterations++;	completelySorted = TRUE;	for (rxQueue = 0;   (rxQueues[rxQueue+1].npeCount != 0)	     && (rxQueue < IX_ETHACC_MAX_RX_QUEUES - sortIterations); 	     rxQueue++)	{	    /* compare adjacent elements */	    if ((rxQueues[rxQueue].trafficClass <		rxQueues[rxQueue+1].trafficClass)		|| ((rxQueues[rxQueue].trafficClass ==

⌨️ 快捷键说明

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