📄 skgeinit.c
字号:
/****************************************************************************** * * Name: skgeinit.c * Project: Gigabit Ethernet Adapters, Common Modules * Version: $Revision: 2.137 $ * Date: $Date: 2008/04/21 14:55:47 $ * Purpose: Contains functions to initialize the adapter * ******************************************************************************//****************************************************************************** * * LICENSE: * (C)Copyright Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * The information in this file is provided "AS IS" without warranty. * /LICENSE * ******************************************************************************/#include "h/skdrv1st.h"#include "h/skdrv2nd.h"/* global variables ***********************************************************//* local variables ************************************************************/#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))static const char SysKonnectFileId[] = "@(#) $Id: skgeinit.c,v 2.137 2008/04/21 14:55:47 rschmidt Exp $ (C) Marvell.";#endifstruct s_QOffTab { int RxQOff; /* Receive Queue Address Offset */ int XsQOff; /* Sync Tx Queue Address Offset */ int XaQOff; /* Async Tx Queue Address Offset */};static struct s_QOffTab QOffTab[] = { {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}};struct s_Config { char ScanString[8]; SK_U32 Value;};static struct s_Config OemConfig = { {'O','E','M','_','C','o','n','f'},#ifdef SK_OEM_CONFIG OEM_CONFIG_VALUE,#else 0,#endif};#ifndef SK_SLIM/****************************************************************************** * * SkGePortVlan() - Enable / Disable VLAN support * * Description: * Enable or disable the VLAN support of the selected port. * The new configuration is *not* saved over any SkGeStopPort() and * SkGeInitPort() calls. * Currently this function is only supported on Yukon-2/EC adapters. * * Returns: * nothing */void SkGePortVlan(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port number */SK_BOOL Enable) /* Flag */{ SK_U32 RxCtrl; SK_U32 TxCtrl; if (CHIP_ID_YUKON_2(pAC)) { if (Enable) { RxCtrl = RX_VLAN_STRIP_ON; TxCtrl = TX_VLAN_TAG_ON; } else { RxCtrl = RX_VLAN_STRIP_OFF; TxCtrl = TX_VLAN_TAG_OFF; } SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), RxCtrl); SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TxCtrl); }} /* SkGePortVlan *//****************************************************************************** * * SkGeRxRss() - Enable / Disable RSS Hash Calculation * * Description: * Enable or disable the RSS hash calculation of the selected port. * The new configuration is *not* saved over any SkGeStopPort() and * SkGeInitPort() calls. * Currently this function is only supported on Yukon-2/EC adapters. * * Returns: * nothing */void SkGeRxRss(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port number */SK_BOOL Enable) /* Flag */{ if (CHIP_ID_YUKON_2(pAC)) { SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR), Enable ? BMU_ENA_RX_RSS_HASH : BMU_DIS_RX_RSS_HASH); }} /* SkGeRxRss *//****************************************************************************** * * SkGeRxCsum() - Enable / Disable Receive Checksum * * Description: * Enable or disable the checksum of the selected port. * The new configuration is *not* saved over any SkGeStopPort() and * SkGeInitPort() calls. * Currently this function is only supported on Yukon-2/EC adapters. * * Returns: * nothing */void SkGeRxCsum(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port number */SK_BOOL Enable) /* Flag */{ if (CHIP_ID_YUKON_2(pAC)) { SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR), Enable ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); }} /* SkGeRxCsum */#endif /* !SK_SLIM */#ifndef DISABLE_YUKON_I/****************************************************************************** * * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring * * Description: * Enable or disable the descriptor polling of the receive descriptor * ring (RxD) for port 'Port'. * The new configuration is *not* saved over any SkGeStopPort() and * SkGeInitPort() calls. * * Returns: * nothing */void SkGePollRxD(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL PollRxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */{ SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (SK_U32)((PollRxD) ? CSR_ENA_POL : CSR_DIS_POL));} /* SkGePollRxD *//****************************************************************************** * * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings * * Description: * Enable or disable the descriptor polling of the transmit descriptor * ring(s) (TxD) for port 'Port'. * The new configuration is *not* saved over any SkGeStopPort() and * SkGeInitPort() calls. * * Returns: * nothing */void SkGePollTxD(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Port, /* Port Index (MAC_1 + n) */SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */{ SK_GEPORT *pPrt; SK_U32 DWord; pPrt = &pAC->GIni.GP[Port]; DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL); if (pPrt->PXSQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord); } if (pPrt->PXAQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord); }} /* SkGePollTxD */#endif /* !DISABLE_YUKON_I */#ifndef SK_SLIM/****************************************************************************** * * SkGeYellowLED() - Switch the yellow LED on or off. * * Description: * Switch the yellow LED on or off. * * Note: * This function may be called any time after SkGeInit(Level 1). * * Returns: * nothing */void SkGeYellowLED(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int State) /* yellow LED state, 0 = OFF, 0 != ON */{ int LedReg; if (CHIP_ID_YUKON_2(pAC)) { /* different mapping on Yukon-2 */ LedReg = B0_CTST + 1; } else { LedReg = B0_LED; } if (State == 0) { /* Switch state LED OFF */ SK_OUT8(IoC, LedReg, LED_STAT_OFF); } else { /* Switch state LED ON */ SK_OUT8(IoC, LedReg, LED_STAT_ON); }} /* SkGeYellowLED */#endif /* !SK_SLIM *//****************************************************************************** * * DoCalcAddr() - Calculates the start and the end address of a queue. * * Description: * This function calculates the start and the end address of a queue. * Afterwards the 'StartVal' is incremented to the next start position. * If the port is already initialized the calculated values * will be checked against the configured values and an * error will be returned, if they are not equal. * If the port is not initialized the values will be written to * *StartAdr and *EndAddr. * * Returns: * 0: success * 1: configuration error */static int DoCalcAddr(SK_AC *pAC, /* Adapter Context */SK_GEPORT SK_FAR *pPrt, /* port index */int QuSize, /* size of the queue to configure in kB */SK_U32 SK_FAR *StartVal, /* start value for address calculation */SK_U32 SK_FAR *QuStartAddr,/* start address to calculate */SK_U32 SK_FAR *QuEndAddr) /* end address to calculate */{ SK_U32 EndVal; SK_U32 NextStart; int Rtv; Rtv = 0; if (QuSize == 0) { EndVal = *StartVal; NextStart = EndVal; } else { EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1; NextStart = EndVal + 1; } if (pPrt->PState >= SK_PRT_INIT) { if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) { Rtv = 1; } } else { *QuStartAddr = *StartVal; *QuEndAddr = EndVal; } *StartVal = NextStart; return(Rtv);} /* DoCalcAddr *//****************************************************************************** * * SkGeRoundQueueSize() - Round the given queue size to the adapters QZ units * * Description: * This function rounds the given queue size in kBs to adapter specific * queue size units (Yukon-1: 8 kB, Yukon-2/EC: 1 kB). * * Returns: * the rounded queue size in kB */static int SkGeRoundQueueSize(SK_AC *pAC, /* Adapter Context */int QueueSizeKB) /* Queue size in kB */{ int QueueSizeSteps; QueueSizeSteps = (CHIP_ID_YUKON_2(pAC)) ? QZ_STEP_Y2 : QZ_STEP; return((QueueSizeKB + QueueSizeSteps - 1) & ~(QueueSizeSteps - 1));} /* SkGeRoundQueueSize *//****************************************************************************** * * SkGeInitAssignRamToQueues() - Allocate default queue sizes * * Description: * This function assigns the memory to the different queues and ports. * When DualNet is set to SK_TRUE all ports get the same amount of memory. * Otherwise the first port gets most of the memory and all the * other ports just the required minimum. * This function can only be called when pAC->GIni.GIRamSize and * pAC->GIni.GIMacsFound have been initialized, usually this happens * at init level 1 * * Returns: * 0 - ok * 1 - invalid input values * 2 - not enough memory */int SkGeInitAssignRamToQueues(SK_AC *pAC, /* Adapter Context */int ActivePort, /* Active Port in RLMT mode */SK_BOOL DualNet) /* Dual Net active */{ int i; int UsedKilobytes; /* memory already assigned */ int ActivePortKilobytes; /* memory available for active port */ int MinQueueSize; /* min. memory for queues */ int TotalRamSize; /* total memory for queues */ SK_BOOL DualPortYukon2; SK_GEPORT *pPrt; if (ActivePort >= pAC->GIni.GIMacsFound) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n", ActivePort)); return(1); } DualPortYukon2 = (CHIP_ID_YUKON_2(pAC) && pAC->GIni.GIMacsFound == 2); TotalRamSize = pAC->GIni.GIRamSize; if (DualPortYukon2) { TotalRamSize *= 2; } MinQueueSize = SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE; if (MinQueueSize > pAC->GIni.GIRamSize) { MinQueueSize = pAC->GIni.GIRamSize; } if ((pAC->GIni.GIMacsFound * MinQueueSize + RAM_QUOTA_SYNC * SK_MIN_TXQ_SIZE) > TotalRamSize) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n", TotalRamSize)); return(2); } if (DualNet) { /* every port gets the same amount of memory */ ActivePortKilobytes = TotalRamSize / pAC->GIni.GIMacsFound; for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pPrt = &pAC->GIni.GP[i]; if (DualPortYukon2) { ActivePortKilobytes = pAC->GIni.GIRamSize; } /* take away the minimum memory for active queues */ ActivePortKilobytes -= MinQueueSize; /* receive queue gets the minimum + 80% of the rest */ pPrt->PRxQSize = SkGeRoundQueueSize(pAC, (int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100) + SK_MIN_RXQ_SIZE; ActivePortKilobytes -= (pPrt->PRxQSize - SK_MIN_RXQ_SIZE); /* synchronous transmit queue */ pPrt->PXSQSize = 0; /* asynchronous transmit queue */ pPrt->PXAQSize = SkGeRoundQueueSize(pAC, ActivePortKilobytes + SK_MIN_TXQ_SIZE); } } else { /* RLMT Mode or single link adapter */ UsedKilobytes = 0; /* set standby queue size defaults for all standby ports */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { if (i != ActivePort) { pPrt = &pAC->GIni.GP[i]; if (DualPortYukon2) { pPrt->PRxQSize = SkGeRoundQueueSize(pAC, (int)((long)(pAC->GIni.GIRamSize - MinQueueSize) * RAM_QUOTA_RX) / 100) + SK_MIN_RXQ_SIZE; pPrt->PXAQSize = pAC->GIni.GIRamSize - pPrt->PRxQSize; } else { pPrt->PRxQSize = SK_MIN_RXQ_SIZE; pPrt->PXAQSize = SK_MIN_TXQ_SIZE; } pPrt->PXSQSize = 0; /* Count used RAM */ UsedKilobytes += pPrt->PRxQSize + pPrt->PXAQSize; } } /* what's left? */ ActivePortKilobytes = TotalRamSize - UsedKilobytes; /* assign it to the active port */ /* first take away the minimum memory */ ActivePortKilobytes -= MinQueueSize; pPrt = &pAC->GIni.GP[ActivePort]; /* receive queue gets 80% of the rest */ pPrt->PRxQSize = SkGeRoundQueueSize(pAC,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -