summaryrefslogtreecommitdiffstats
path: root/drivers/net/sk98lin/skdim.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sk98lin/skdim.c')
-rw-r--r--drivers/net/sk98lin/skdim.c742
1 files changed, 742 insertions, 0 deletions
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c
new file mode 100644
index 00000000000..0fddf61047b
--- /dev/null
+++ b/drivers/net/sk98lin/skdim.c
@@ -0,0 +1,742 @@
+/******************************************************************************
+ *
+ * Name: skdim.c
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.5 $
+ * Date: $Date: 2003/11/28 12:55:40 $
+ * Purpose: All functions to maintain interrupt moderation
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This module is intended to manage the dynamic interrupt moderation on both
+ * GEnesis and Yukon adapters.
+ *
+ * Include File Hierarchy:
+ *
+ * "skdrv1st.h"
+ * "skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#ifndef lint
+static const char SysKonnectFileId[] =
+ "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
+#endif
+
+#define __SKADDR_C
+
+#ifdef __cplusplus
+#error C++ is not yet supported.
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Includes
+**
+*******************************************************************************/
+
+#ifndef __INC_SKDRV1ST_H
+#include "h/skdrv1st.h"
+#endif
+
+#ifndef __INC_SKDRV2ND_H
+#include "h/skdrv2nd.h"
+#endif
+
+#include <linux/kernel_stat.h>
+
+/*******************************************************************************
+**
+** Defines
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Typedefs
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Local function prototypes
+**
+*******************************************************************************/
+
+static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
+static SK_U64 GetIsrCalls(SK_AC *pAC);
+static SK_BOOL IsIntModEnabled(SK_AC *pAC);
+static void SetCurrIntCtr(SK_AC *pAC);
+static void EnableIntMod(SK_AC *pAC);
+static void DisableIntMod(SK_AC *pAC);
+static void ResizeDimTimerDuration(SK_AC *pAC);
+static void DisplaySelectedModerationType(SK_AC *pAC);
+static void DisplaySelectedModerationMask(SK_AC *pAC);
+static void DisplayDescrRatio(SK_AC *pAC);
+
+/*******************************************************************************
+**
+** Global variables
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Local variables
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Global functions
+**
+*******************************************************************************/
+
+/*******************************************************************************
+** Function : SkDimModerate
+** Description : Called in every ISR to check if moderation is to be applied
+** or not for the current number of interrupts
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : void (!)
+** Notes : -
+*******************************************************************************/
+
+void
+SkDimModerate(SK_AC *pAC) {
+ unsigned int CurrSysLoad = 0; /* expressed in percent */
+ unsigned int LoadIncrease = 0; /* expressed in percent */
+ SK_U64 ThresholdInts = 0;
+ SK_U64 IsrCallsPerSec = 0;
+
+#define M_DIMINFO pAC->DynIrqModInfo
+
+ if (!IsIntModEnabled(pAC)) {
+ if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+ CurrSysLoad = GetCurrentSystemLoad(pAC);
+ if (CurrSysLoad > 75) {
+ /*
+ ** More than 75% total system load! Enable the moderation
+ ** to shield the system against too many interrupts.
+ */
+ EnableIntMod(pAC);
+ } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
+ LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
+ if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
+ C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
+ if (CurrSysLoad > 10) {
+ /*
+ ** More than 50% increase with respect to the
+ ** previous load of the system. Most likely this
+ ** is due to our ISR-proc...
+ */
+ EnableIntMod(pAC);
+ }
+ }
+ } else {
+ /*
+ ** Neither too much system load at all nor too much increase
+ ** with respect to the previous system load. Hence, we can leave
+ ** the ISR-handling like it is without enabling moderation.
+ */
+ }
+ M_DIMINFO.PrevSysLoad = CurrSysLoad;
+ }
+ } else {
+ if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+ ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
+ C_INT_MOD_DISABLE_PERCENTAGE) / 100);
+ IsrCallsPerSec = GetIsrCalls(pAC);
+ if (IsrCallsPerSec <= ThresholdInts) {
+ /*
+ ** The number of interrupts within the last second is
+ ** lower than the disable_percentage of the desried
+ ** maxrate. Therefore we can disable the moderation.
+ */
+ DisableIntMod(pAC);
+ M_DIMINFO.MaxModIntsPerSec =
+ (M_DIMINFO.MaxModIntsPerSecUpperLimit +
+ M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
+ } else {
+ /*
+ ** The number of interrupts per sec is the same as expected.
+ ** Evalulate the descriptor-ratio. If it has changed, a resize
+ ** in the moderation timer might be usefull
+ */
+ if (M_DIMINFO.AutoSizing) {
+ ResizeDimTimerDuration(pAC);
+ }
+ }
+ }
+ }
+
+ /*
+ ** Some information to the log...
+ */
+ if (M_DIMINFO.DisplayStats) {
+ DisplaySelectedModerationType(pAC);
+ DisplaySelectedModerationMask(pAC);
+ DisplayDescrRatio(pAC);
+ }
+
+ M_DIMINFO.NbrProcessedDescr = 0;
+ SetCurrIntCtr(pAC);
+}
+
+/*******************************************************************************
+** Function : SkDimStartModerationTimer
+** Description : Starts the audit-timer for the dynamic interrupt moderation
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : void (!)
+** Notes : -
+*******************************************************************************/
+
+void
+SkDimStartModerationTimer(SK_AC *pAC) {
+ SK_EVPARA EventParam; /* Event struct for timer event */
+
+ SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
+ EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
+ SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
+ SK_DRV_MODERATION_TIMER_LENGTH,
+ SKGE_DRV, SK_DRV_TIMER, EventParam);
+}
+
+/*******************************************************************************
+** Function : SkDimEnableModerationIfNeeded
+** Description : Either enables or disables moderation
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : void (!)
+** Notes : This function is called when a particular adapter is opened
+** There is no Disable function, because when all interrupts
+** might be disable, the moderation timer has no meaning at all
+******************************************************************************/
+
+void
+SkDimEnableModerationIfNeeded(SK_AC *pAC) {
+
+ if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
+ EnableIntMod(pAC); /* notification print in this function */
+ } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+ SkDimStartModerationTimer(pAC);
+ if (M_DIMINFO.DisplayStats) {
+ printk("Dynamic moderation has been enabled\n");
+ }
+ } else {
+ if (M_DIMINFO.DisplayStats) {
+ printk("No moderation has been enabled\n");
+ }
+ }
+}
+
+/*******************************************************************************
+** Function : SkDimDisplayModerationSettings
+** Description : Displays the current settings regaring interrupt moderation
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : void (!)
+** Notes : -
+*******************************************************************************/
+
+void
+SkDimDisplayModerationSettings(SK_AC *pAC) {
+ DisplaySelectedModerationType(pAC);
+ DisplaySelectedModerationMask(pAC);
+}
+
+/*******************************************************************************
+**
+** Local functions
+**
+*******************************************************************************/
+
+/*******************************************************************************
+** Function : GetCurrentSystemLoad
+** Description : Retrieves the current system load of the system. This load
+** is evaluated for all processors within the system.
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : unsigned int: load expressed in percentage
+** Notes : The possible range being returned is from 0 up to 100.
+** Whereas 0 means 'no load at all' and 100 'system fully loaded'
+** It is impossible to determine what actually causes the system
+** to be in 100%, but maybe that is due to too much interrupts.
+*******************************************************************************/
+
+static unsigned int
+GetCurrentSystemLoad(SK_AC *pAC) {
+ unsigned long jif = jiffies;
+ unsigned int UserTime = 0;
+ unsigned int SystemTime = 0;
+ unsigned int NiceTime = 0;
+ unsigned int IdleTime = 0;
+ unsigned int TotalTime = 0;
+ unsigned int UsedTime = 0;
+ unsigned int SystemLoad = 0;
+
+ /* unsigned int NbrCpu = 0; */
+
+ /*
+ ** The following lines have been commented out, because
+ ** from kernel 2.5.44 onwards, the kernel-owned structure
+ **
+ ** struct kernel_stat kstat
+ **
+ ** is not marked as an exported symbol in the file
+ **
+ ** kernel/ksyms.c
+ **
+ ** As a consequence, using this driver as KLM is not possible
+ ** and any access of the structure kernel_stat via the
+ ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.
+ **
+ ** The kstat-information might be added again in future
+ ** versions of the 2.5.xx kernel, but for the time being,
+ ** number of interrupts will serve as indication how much
+ ** load we currently have...
+ **
+ ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {
+ ** UserTime = UserTime + kstat_cpu(NbrCpu).cpustat.user;
+ ** NiceTime = NiceTime + kstat_cpu(NbrCpu).cpustat.nice;
+ ** SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;
+ ** }
+ */
+ SK_U64 ThresholdInts = 0;
+ SK_U64 IsrCallsPerSec = 0;
+
+ ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
+ C_INT_MOD_ENABLE_PERCENTAGE) + 100);
+ IsrCallsPerSec = GetIsrCalls(pAC);
+ if (IsrCallsPerSec >= ThresholdInts) {
+ /*
+ ** We do not know how much the real CPU-load is!
+ ** Return 80% as a default in order to activate DIM
+ */
+ SystemLoad = 80;
+ return (SystemLoad);
+ }
+
+ UsedTime = UserTime + NiceTime + SystemTime;
+
+ IdleTime = jif * num_online_cpus() - UsedTime;
+ TotalTime = UsedTime + IdleTime;
+
+ SystemLoad = ( 100 * (UsedTime - M_DIMINFO.PrevUsedTime) ) /
+ (TotalTime - M_DIMINFO.PrevTotalTime);
+
+ if (M_DIMINFO.DisplayStats) {
+ printk("Current system load is: %u\n", SystemLoad);
+ }
+
+ M_DIMINFO.PrevTotalTime = TotalTime;
+ M_DIMINFO.PrevUsedTime = UsedTime;
+
+ return (SystemLoad);
+}
+
+/*******************************************************************************
+** Function : GetIsrCalls
+** Description : Depending on the selected moderation mask, this function will
+** return the number of interrupts handled in the previous time-
+** frame. This evaluated number is based on the current number
+** of interrupts stored in PNMI-context and the previous stored
+** interrupts.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : int: the number of interrupts being executed in the last
+** timeframe
+** Notes : It makes only sense to call this function, when dynamic
+** interrupt moderation is applied
+*******************************************************************************/
+
+static SK_U64
+GetIsrCalls(SK_AC *pAC) {
+ SK_U64 RxPort0IntDiff = 0;
+ SK_U64 RxPort1IntDiff = 0;
+ SK_U64 TxPort0IntDiff = 0;
+ SK_U64 TxPort1IntDiff = 0;
+
+ if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
+ if (pAC->GIni.GIMacsFound == 2) {
+ TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1TxIntrCts;
+ }
+ TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0TxIntrCts;
+ } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
+ if (pAC->GIni.GIMacsFound == 2) {
+ RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1RxIntrCts;
+ }
+ RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0RxIntrCts;
+ } else {
+ if (pAC->GIni.GIMacsFound == 2) {
+ RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1RxIntrCts;
+ TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1TxIntrCts;
+ }
+ RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0RxIntrCts;
+ TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0TxIntrCts;
+ }
+
+ return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
+}
+
+/*******************************************************************************
+** Function : GetRxCalls
+** Description : This function will return the number of times a receive inter-
+** rupt was processed. This is needed to evaluate any resizing
+** factor.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : SK_U64: the number of RX-ints being processed
+** Notes : It makes only sense to call this function, when dynamic
+** interrupt moderation is applied
+*******************************************************************************/
+
+static SK_U64
+GetRxCalls(SK_AC *pAC) {
+ SK_U64 RxPort0IntDiff = 0;
+ SK_U64 RxPort1IntDiff = 0;
+
+ if (pAC->GIni.GIMacsFound == 2) {
+ RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1RxIntrCts;
+ }
+ RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0RxIntrCts;
+
+ return (RxPort0IntDiff + RxPort1IntDiff);
+}
+
+/*******************************************************************************
+** Function : SetCurrIntCtr
+** Description : Will store the current number orf occured interrupts in the
+** adapter context. This is needed to evaluated the number of
+** interrupts within a current timeframe.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : void (!)
+** Notes : -
+*******************************************************************************/
+
+static void
+SetCurrIntCtr(SK_AC *pAC) {
+ if (pAC->GIni.GIMacsFound == 2) {
+ pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
+ pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
+ }
+ pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
+ pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
+}
+
+/*******************************************************************************
+** Function : IsIntModEnabled()
+** Description : Retrieves the current value of the interrupts moderation
+** command register. Its content determines whether any
+** moderation is running or not.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : SK_TRUE : if mod timer running
+** SK_FALSE : if no moderation is being performed
+** Notes : -
+*******************************************************************************/
+
+static SK_BOOL
+IsIntModEnabled(SK_AC *pAC) {
+ unsigned long CtrCmd;
+
+ SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
+ if ((CtrCmd & TIM_START) == TIM_START) {
+ return SK_TRUE;
+ } else {
+ return SK_FALSE;
+ }
+}
+
+/*******************************************************************************
+** Function : EnableIntMod()
+** Description : Enables the interrupt moderation using the values stored in
+** in the pAC->DynIntMod data structure
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : -
+** Notes : -
+*******************************************************************************/
+
+static void
+EnableIntMod(SK_AC *pAC) {
+ unsigned long ModBase;
+
+ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+ ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
+ } else {
+ ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
+ }
+
+ SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
+ SK_OUT32(pAC->IoBase, B2_IRQM_MSK, pAC->DynIrqModInfo.MaskIrqModeration);
+ SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
+ if (M_DIMINFO.DisplayStats) {
+ printk("Enabled interrupt moderation (%i ints/sec)\n",
+ M_DIMINFO.MaxModIntsPerSec);
+ }
+}
+
+/*******************************************************************************
+** Function : DisableIntMod()
+** Description : Disbles the interrupt moderation independent of what inter-
+** rupts are running or not
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : -
+** Notes : -
+*******************************************************************************/
+
+static void
+DisableIntMod(SK_AC *pAC) {
+
+ SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
+ if (M_DIMINFO.DisplayStats) {
+ printk("Disabled interrupt moderation\n");
+ }
+}
+
+/*******************************************************************************
+** Function : ResizeDimTimerDuration();
+** Description : Checks the current used descriptor ratio and resizes the
+** duration timer (longer/smaller) if possible.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : -
+** Notes : There are both maximum and minimum timer duration value.
+** This function assumes that interrupt moderation is already
+** enabled!
+*******************************************************************************/
+
+static void
+ResizeDimTimerDuration(SK_AC *pAC) {
+ SK_BOOL IncreaseTimerDuration;
+ int TotalMaxNbrDescr;
+ int UsedDescrRatio;
+ int RatioDiffAbs;
+ int RatioDiffRel;
+ int NewMaxModIntsPerSec;
+ int ModAdjValue;
+ long ModBase;
+
+ /*
+ ** Check first if we are allowed to perform any modification
+ */
+ if (IsIntModEnabled(pAC)) {
+ if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
+ return;
+ } else {
+ if (M_DIMINFO.ModJustEnabled) {
+ M_DIMINFO.ModJustEnabled = SK_FALSE;
+ return;
+ }
+ }
+ }
+
+ /*
+ ** If we got until here, we have to evaluate the amount of the
+ ** descriptor ratio change...
+ */
+ TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
+ UsedDescrRatio = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
+
+ if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
+ RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
+ RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
+ M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
+ IncreaseTimerDuration = SK_FALSE; /* in other words: DECREASE */
+ } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
+ RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
+ RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
+ M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
+ IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
+ } else {
+ RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
+ RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
+ M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
+ IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
+ }
+
+ /*
+ ** Now we can determine the change in percent
+ */
+ if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
+ ModAdjValue = 1; /* 1% change - maybe some other value in future */
+ } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
+ ModAdjValue = 1; /* 1% change - maybe some other value in future */
+ } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
+ ModAdjValue = 1; /* 1% change - maybe some other value in future */
+ } else {
+ ModAdjValue = 1; /* 1% change - maybe some other value in future */
+ }
+
+ if (IncreaseTimerDuration) {
+ NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec +
+ (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
+ } else {
+ NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec -
+ (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
+ }
+
+ /*
+ ** Check if we exceed boundaries...
+ */
+ if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
+ (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
+ if (M_DIMINFO.DisplayStats) {
+ printk("Cannot change ModTim from %i to %i ints/sec\n",
+ M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
+ }
+ return;
+ } else {
+ if (M_DIMINFO.DisplayStats) {
+ printk("Resized ModTim from %i to %i ints/sec\n",
+ M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
+ }
+ }
+
+ M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
+
+ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+ ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
+ } else {
+ ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
+ }
+
+ /*
+ ** We do not need to touch any other registers
+ */
+ SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
+}
+
+/*******************************************************************************
+** Function : DisplaySelectedModerationType()
+** Description : Displays what type of moderation we have
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : void!
+** Notes : -
+*******************************************************************************/
+
+static void
+DisplaySelectedModerationType(SK_AC *pAC) {
+
+ if (pAC->DynIrqModInfo.DisplayStats) {
+ if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
+ printk("Static int moderation runs with %i INTS/sec\n",
+ pAC->DynIrqModInfo.MaxModIntsPerSec);
+ } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+ if (IsIntModEnabled(pAC)) {
+ printk("Dynamic int moderation runs with %i INTS/sec\n",
+ pAC->DynIrqModInfo.MaxModIntsPerSec);
+ } else {
+ printk("Dynamic int moderation currently not applied\n");
+ }
+ } else {
+ printk("No interrupt moderation selected!\n");
+ }
+ }
+}
+
+/*******************************************************************************
+** Function : DisplaySelectedModerationMask()
+** Description : Displays what interrupts are moderated
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : void!
+** Notes : -
+*******************************************************************************/
+
+static void
+DisplaySelectedModerationMask(SK_AC *pAC) {
+
+ if (pAC->DynIrqModInfo.DisplayStats) {
+ if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
+ switch (pAC->DynIrqModInfo.MaskIrqModeration) {
+ case IRQ_MASK_TX_ONLY:
+ printk("Only Tx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_RX_ONLY:
+ printk("Only Rx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_SP_ONLY:
+ printk("Only special-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_TX_RX:
+ printk("Tx- and Rx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_SP_RX:
+ printk("Special- and Rx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_SP_TX:
+ printk("Special- and Tx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_RX_TX_SP:
+ printk("All Rx-, Tx and special-interrupts are moderated\n");
+ break;
+ default:
+ printk("Don't know what is moderated\n");
+ break;
+ }
+ } else {
+ printk("No specific interrupts masked for moderation\n");
+ }
+ }
+}
+
+/*******************************************************************************
+** Function : DisplayDescrRatio
+** Description : Like the name states...
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : void!
+** Notes : -
+*******************************************************************************/
+
+static void
+DisplayDescrRatio(SK_AC *pAC) {
+ int TotalMaxNbrDescr = 0;
+
+ if (pAC->DynIrqModInfo.DisplayStats) {
+ TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
+ printk("Ratio descriptors: %i/%i\n",
+ M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
+ }
+}
+
+/*******************************************************************************
+**
+** End of file
+**
+*******************************************************************************/