/******************************************************************************
*
* 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 useful
*/
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
**
*******************************************************************************/