1/******************************************************************************
2 *
3 * Name:	skdim.c
4 * Project:	GEnesis, PCI Gigabit Ethernet Adapter
5 * Version:	$Revision: 1.1.1.1 $
6 * Date:	$Date: 2007-08-03 18:52:48 $
7 * Purpose:	All functions to maintain interrupt moderation
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 *	(C)Copyright 1998-2002 SysKonnect GmbH.
14 *	(C)Copyright 2002-2003 Marvell.
15 *
16 *	This program is free software; you can redistribute it and/or modify
17 *	it under the terms of the GNU General Public License as published by
18 *	the Free Software Foundation; either version 2 of the License, or
19 *	(at your option) any later version.
20 *
21 *	The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage the dynamic interrupt moderation on both
30 * GEnesis and Yukon adapters.
31 *
32 * Include File Hierarchy:
33 *
34 *	"skdrv1st.h"
35 *	"skdrv2nd.h"
36 *
37 ******************************************************************************/
38
39#ifndef	lint
40static const char SysKonnectFileId[] =
41	"@(#) $Id: skdim.c,v 1.1.1.1 2007-08-03 18:52:48 $ (C) SysKonnect.";
42#endif
43
44#define __SKADDR_C
45
46#ifdef __cplusplus
47#error C++ is not yet supported.
48extern "C" {
49#endif
50
51/*******************************************************************************
52**
53** Includes
54**
55*******************************************************************************/
56
57#ifndef __INC_SKDRV1ST_H
58#include "h/skdrv1st.h"
59#endif
60
61#ifndef __INC_SKDRV2ND_H
62#include "h/skdrv2nd.h"
63#endif
64
65#include	<linux/kernel_stat.h>
66
67/*******************************************************************************
68**
69** Defines
70**
71*******************************************************************************/
72
73/*******************************************************************************
74**
75** Typedefs
76**
77*******************************************************************************/
78
79/*******************************************************************************
80**
81** Local function prototypes
82**
83*******************************************************************************/
84
85static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
86static SK_U64       GetIsrCalls(SK_AC *pAC);
87static SK_BOOL      IsIntModEnabled(SK_AC *pAC);
88static void         SetCurrIntCtr(SK_AC *pAC);
89static void         EnableIntMod(SK_AC *pAC);
90static void         DisableIntMod(SK_AC *pAC);
91static void         ResizeDimTimerDuration(SK_AC *pAC);
92static void         DisplaySelectedModerationType(SK_AC *pAC);
93static void         DisplaySelectedModerationMask(SK_AC *pAC);
94static void         DisplayDescrRatio(SK_AC *pAC);
95
96/*******************************************************************************
97**
98** Global variables
99**
100*******************************************************************************/
101
102/*******************************************************************************
103**
104** Local variables
105**
106*******************************************************************************/
107
108/*******************************************************************************
109**
110** Global functions
111**
112*******************************************************************************/
113
114/*******************************************************************************
115** Function     : SkDimModerate
116** Description  : Called in every ISR to check if moderation is to be applied
117**                or not for the current number of interrupts
118** Programmer   : Ralph Roesler
119** Last Modified: 22-mar-03
120** Returns      : void (!)
121** Notes        : -
122*******************************************************************************/
123
124void
125SkDimModerate(SK_AC *pAC) {
126    unsigned int CurrSysLoad    = 0;  /* expressed in percent */
127    unsigned int LoadIncrease   = 0;  /* expressed in percent */
128    SK_U64       ThresholdInts  = 0;
129    SK_U64       IsrCallsPerSec = 0;
130
131#define M_DIMINFO pAC->DynIrqModInfo
132
133    if (!IsIntModEnabled(pAC)) {
134        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
135            CurrSysLoad = GetCurrentSystemLoad(pAC);
136            if (CurrSysLoad > 75) {
137                    /*
138                    ** More than 75% total system load! Enable the moderation
139                    ** to shield the system against too many interrupts.
140                    */
141                    EnableIntMod(pAC);
142            } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
143                LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
144                if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
145                                         C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
146                    if (CurrSysLoad > 10) {
147                        /*
148                        ** More than 50% increase with respect to the
149                        ** previous load of the system. Most likely this
150                        ** is due to our ISR-proc...
151                        */
152                        EnableIntMod(pAC);
153                    }
154                }
155            } else {
156                /*
157                ** Neither too much system load at all nor too much increase
158                ** with respect to the previous system load. Hence, we can leave
159                ** the ISR-handling like it is without enabling moderation.
160                */
161            }
162            M_DIMINFO.PrevSysLoad = CurrSysLoad;
163        }
164    } else {
165        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
166            ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *
167                                   C_INT_MOD_DISABLE_PERCENTAGE) / 100);
168            IsrCallsPerSec = GetIsrCalls(pAC);
169            if (IsrCallsPerSec <= ThresholdInts) {
170                /*
171                ** The number of interrupts within the last second is
172                ** lower than the disable_percentage of the desried
173                ** maxrate. Therefore we can disable the moderation.
174                */
175                DisableIntMod(pAC);
176                M_DIMINFO.MaxModIntsPerSec =
177                   (M_DIMINFO.MaxModIntsPerSecUpperLimit +
178                    M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
179            } else {
180                /*
181                ** The number of interrupts per sec is the same as expected.
182                ** Evalulate the descriptor-ratio. If it has changed, a resize
183                ** in the moderation timer might be useful
184                */
185                if (M_DIMINFO.AutoSizing) {
186                    ResizeDimTimerDuration(pAC);
187                }
188            }
189        }
190    }
191
192    /*
193    ** Some information to the log...
194    */
195    if (M_DIMINFO.DisplayStats) {
196        DisplaySelectedModerationType(pAC);
197        DisplaySelectedModerationMask(pAC);
198        DisplayDescrRatio(pAC);
199    }
200
201    M_DIMINFO.NbrProcessedDescr = 0;
202    SetCurrIntCtr(pAC);
203}
204
205/*******************************************************************************
206** Function     : SkDimStartModerationTimer
207** Description  : Starts the audit-timer for the dynamic interrupt moderation
208** Programmer   : Ralph Roesler
209** Last Modified: 22-mar-03
210** Returns      : void (!)
211** Notes        : -
212*******************************************************************************/
213
214void
215SkDimStartModerationTimer(SK_AC *pAC) {
216    SK_EVPARA    EventParam;   /* Event struct for timer event */
217
218    SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
219    EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
220    SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
221                 SK_DRV_MODERATION_TIMER_LENGTH,
222                 SKGE_DRV, SK_DRV_TIMER, EventParam);
223}
224
225/*******************************************************************************
226** Function     : SkDimEnableModerationIfNeeded
227** Description  : Either enables or disables moderation
228** Programmer   : Ralph Roesler
229** Last Modified: 22-mar-03
230** Returns      : void (!)
231** Notes        : This function is called when a particular adapter is opened
232**                There is no Disable function, because when all interrupts
233**                might be disable, the moderation timer has no meaning at all
234******************************************************************************/
235
236void
237SkDimEnableModerationIfNeeded(SK_AC *pAC) {
238
239    if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
240        EnableIntMod(pAC);   /* notification print in this function */
241    } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
242        SkDimStartModerationTimer(pAC);
243        if (M_DIMINFO.DisplayStats) {
244            printk("Dynamic moderation has been enabled\n");
245        }
246    } else {
247        if (M_DIMINFO.DisplayStats) {
248            printk("No moderation has been enabled\n");
249        }
250    }
251}
252
253/*******************************************************************************
254** Function     : SkDimDisplayModerationSettings
255** Description  : Displays the current settings regarding interrupt moderation
256** Programmer   : Ralph Roesler
257** Last Modified: 22-mar-03
258** Returns      : void (!)
259** Notes        : -
260*******************************************************************************/
261
262void
263SkDimDisplayModerationSettings(SK_AC *pAC) {
264    DisplaySelectedModerationType(pAC);
265    DisplaySelectedModerationMask(pAC);
266}
267
268/*******************************************************************************
269**
270** Local functions
271**
272*******************************************************************************/
273
274/*******************************************************************************
275** Function     : GetCurrentSystemLoad
276** Description  : Retrieves the current system load of the system. This load
277**                is evaluated for all processors within the system.
278** Programmer   : Ralph Roesler
279** Last Modified: 22-mar-03
280** Returns      : unsigned int: load expressed in percentage
281** Notes        : The possible range being returned is from 0 up to 100.
282**                Whereas 0 means 'no load at all' and 100 'system fully loaded'
283**                It is impossible to determine what actually causes the system
284**                to be in 100%, but maybe that is due to too much interrupts.
285*******************************************************************************/
286
287static unsigned int
288GetCurrentSystemLoad(SK_AC *pAC) {
289	unsigned long jif         = jiffies;
290	unsigned int  UserTime    = 0;
291	unsigned int  SystemTime  = 0;
292	unsigned int  NiceTime    = 0;
293	unsigned int  IdleTime    = 0;
294	unsigned int  TotalTime   = 0;
295	unsigned int  UsedTime    = 0;
296	unsigned int  SystemLoad  = 0;
297
298	/* unsigned int  NbrCpu      = 0; */
299
300	SK_U64 ThresholdInts  = 0;
301	SK_U64 IsrCallsPerSec = 0;
302
303	ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *
304			   C_INT_MOD_ENABLE_PERCENTAGE) + 100);
305	IsrCallsPerSec = GetIsrCalls(pAC);
306	if (IsrCallsPerSec >= ThresholdInts) {
307	    /*
308	    ** We do not know how much the real CPU-load is!
309	    ** Return 80% as a default in order to activate DIM
310	    */
311	    SystemLoad = 80;
312	    return (SystemLoad);
313	}
314
315	UsedTime  = UserTime + NiceTime + SystemTime;
316
317	IdleTime  = jif * num_online_cpus() - UsedTime;
318	TotalTime = UsedTime + IdleTime;
319
320	SystemLoad = ( 100 * (UsedTime  - M_DIMINFO.PrevUsedTime) ) /
321						(TotalTime - M_DIMINFO.PrevTotalTime);
322
323	if (M_DIMINFO.DisplayStats) {
324		printk("Current system load is: %u\n", SystemLoad);
325	}
326
327	M_DIMINFO.PrevTotalTime = TotalTime;
328	M_DIMINFO.PrevUsedTime  = UsedTime;
329
330	return (SystemLoad);
331}
332
333/*******************************************************************************
334** Function     : GetIsrCalls
335** Description  : Depending on the selected moderation mask, this function will
336**                return the number of interrupts handled in the previous time-
337**                frame. This evaluated number is based on the current number
338**                of interrupts stored in PNMI-context and the previous stored
339**                interrupts.
340** Programmer   : Ralph Roesler
341** Last Modified: 23-mar-03
342** Returns      : int:   the number of interrupts being executed in the last
343**                       timeframe
344** Notes        : It makes only sense to call this function, when dynamic
345**                interrupt moderation is applied
346*******************************************************************************/
347
348static SK_U64
349GetIsrCalls(SK_AC *pAC) {
350    SK_U64   RxPort0IntDiff = 0;
351    SK_U64   RxPort1IntDiff = 0;
352    SK_U64   TxPort0IntDiff = 0;
353    SK_U64   TxPort1IntDiff = 0;
354
355    if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
356        if (pAC->GIni.GIMacsFound == 2) {
357            TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
358                             pAC->DynIrqModInfo.PrevPort1TxIntrCts;
359        }
360        TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
361                         pAC->DynIrqModInfo.PrevPort0TxIntrCts;
362    } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
363        if (pAC->GIni.GIMacsFound == 2) {
364            RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
365                             pAC->DynIrqModInfo.PrevPort1RxIntrCts;
366        }
367        RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
368                         pAC->DynIrqModInfo.PrevPort0RxIntrCts;
369    } else {
370        if (pAC->GIni.GIMacsFound == 2) {
371            RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
372                             pAC->DynIrqModInfo.PrevPort1RxIntrCts;
373            TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
374                             pAC->DynIrqModInfo.PrevPort1TxIntrCts;
375        }
376        RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
377                         pAC->DynIrqModInfo.PrevPort0RxIntrCts;
378        TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
379                         pAC->DynIrqModInfo.PrevPort0TxIntrCts;
380    }
381
382    return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
383}
384
385/*******************************************************************************
386** Function     : GetRxCalls
387** Description  : This function will return the number of times a receive inter-
388**                rupt was processed. This is needed to evaluate any resizing
389**                factor.
390** Programmer   : Ralph Roesler
391** Last Modified: 23-mar-03
392** Returns      : SK_U64: the number of RX-ints being processed
393** Notes        : It makes only sense to call this function, when dynamic
394**                interrupt moderation is applied
395*******************************************************************************/
396
397static SK_U64
398GetRxCalls(SK_AC *pAC) {
399    SK_U64   RxPort0IntDiff = 0;
400    SK_U64   RxPort1IntDiff = 0;
401
402    if (pAC->GIni.GIMacsFound == 2) {
403        RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
404                         pAC->DynIrqModInfo.PrevPort1RxIntrCts;
405    }
406    RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
407                     pAC->DynIrqModInfo.PrevPort0RxIntrCts;
408
409    return (RxPort0IntDiff + RxPort1IntDiff);
410}
411
412/*******************************************************************************
413** Function     : SetCurrIntCtr
414** Description  : Will store the current number orf occured interrupts in the
415**                adapter context. This is needed to evaluated the number of
416**                interrupts within a current timeframe.
417** Programmer   : Ralph Roesler
418** Last Modified: 23-mar-03
419** Returns      : void (!)
420** Notes        : -
421*******************************************************************************/
422
423static void
424SetCurrIntCtr(SK_AC *pAC) {
425    if (pAC->GIni.GIMacsFound == 2) {
426        pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
427        pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
428    }
429    pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
430    pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
431}
432
433/*******************************************************************************
434** Function     : IsIntModEnabled()
435** Description  : Retrieves the current value of the interrupts moderation
436**                command register. Its content determines whether any
437**                moderation is running or not.
438** Programmer   : Ralph Roesler
439** Last Modified: 23-mar-03
440** Returns      : SK_TRUE  : if mod timer running
441**                SK_FALSE : if no moderation is being performed
442** Notes        : -
443*******************************************************************************/
444
445static SK_BOOL
446IsIntModEnabled(SK_AC *pAC) {
447    unsigned long CtrCmd;
448
449    SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
450    if ((CtrCmd & TIM_START) == TIM_START) {
451       return SK_TRUE;
452    } else {
453       return SK_FALSE;
454    }
455}
456
457/*******************************************************************************
458** Function     : EnableIntMod()
459** Description  : Enables the interrupt moderation using the values stored in
460**                in the pAC->DynIntMod data structure
461** Programmer   : Ralph Roesler
462** Last Modified: 22-mar-03
463** Returns      : -
464** Notes        : -
465*******************************************************************************/
466
467static void
468EnableIntMod(SK_AC *pAC) {
469    unsigned long ModBase;
470
471    if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
472       ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
473    } else {
474       ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
475    }
476
477    SK_OUT32(pAC->IoBase, B2_IRQM_INI,  ModBase);
478    SK_OUT32(pAC->IoBase, B2_IRQM_MSK,  pAC->DynIrqModInfo.MaskIrqModeration);
479    SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
480    if (M_DIMINFO.DisplayStats) {
481        printk("Enabled interrupt moderation (%i ints/sec)\n",
482               M_DIMINFO.MaxModIntsPerSec);
483    }
484}
485
486/*******************************************************************************
487** Function     : DisableIntMod()
488** Description  : Disables the interrupt moderation independent of what inter-
489**                rupts are running or not
490** Programmer   : Ralph Roesler
491** Last Modified: 23-mar-03
492** Returns      : -
493** Notes        : -
494*******************************************************************************/
495
496static void
497DisableIntMod(SK_AC *pAC) {
498
499    SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
500    if (M_DIMINFO.DisplayStats) {
501        printk("Disabled interrupt moderation\n");
502    }
503}
504
505/*******************************************************************************
506** Function     : ResizeDimTimerDuration();
507** Description  : Checks the current used descriptor ratio and resizes the
508**                duration timer (longer/smaller) if possible.
509** Programmer   : Ralph Roesler
510** Last Modified: 23-mar-03
511** Returns      : -
512** Notes        : There are both maximum and minimum timer duration value.
513**                This function assumes that interrupt moderation is already
514**                enabled!
515*******************************************************************************/
516
517static void
518ResizeDimTimerDuration(SK_AC *pAC) {
519    SK_BOOL IncreaseTimerDuration;
520    int     TotalMaxNbrDescr;
521    int     UsedDescrRatio;
522    int     RatioDiffAbs;
523    int     RatioDiffRel;
524    int     NewMaxModIntsPerSec;
525    int     ModAdjValue;
526    long    ModBase;
527
528    /*
529    ** Check first if we are allowed to perform any modification
530    */
531    if (IsIntModEnabled(pAC)) {
532        if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
533            return;
534        } else {
535            if (M_DIMINFO.ModJustEnabled) {
536                M_DIMINFO.ModJustEnabled = SK_FALSE;
537                return;
538            }
539        }
540    }
541
542    /*
543    ** If we got until here, we have to evaluate the amount of the
544    ** descriptor ratio change...
545    */
546    TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
547    UsedDescrRatio   = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
548
549    if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
550        RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
551        RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
552        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
553        IncreaseTimerDuration = SK_FALSE;  /* in other words: DECREASE */
554    } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
555        RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
556        RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
557        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
558        IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
559    } else {
560        RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
561        RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
562        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
563        IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
564    }
565
566    /*
567    ** Now we can determine the change in percent
568    */
569    if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
570       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
571    } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
572       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
573    } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
574       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
575    } else {
576       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
577    }
578
579    if (IncreaseTimerDuration) {
580       NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec +
581                             (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
582    } else {
583       NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec -
584                             (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
585    }
586
587    /*
588    ** Check if we exceed boundaries...
589    */
590    if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
591         (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
592        if (M_DIMINFO.DisplayStats) {
593            printk("Cannot change ModTim from %i to %i ints/sec\n",
594                   M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
595        }
596        return;
597    } else {
598        if (M_DIMINFO.DisplayStats) {
599            printk("Resized ModTim from %i to %i ints/sec\n",
600                   M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
601        }
602    }
603
604    M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
605
606    if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
607        ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
608    } else {
609        ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
610    }
611
612    /*
613    ** We do not need to touch any other registers
614    */
615    SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
616}
617
618/*******************************************************************************
619** Function     : DisplaySelectedModerationType()
620** Description  : Displays what type of moderation we have
621** Programmer   : Ralph Roesler
622** Last Modified: 23-mar-03
623** Returns      : void!
624** Notes        : -
625*******************************************************************************/
626
627static void
628DisplaySelectedModerationType(SK_AC *pAC) {
629
630    if (pAC->DynIrqModInfo.DisplayStats) {
631        if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
632             printk("Static int moderation runs with %i INTS/sec\n",
633                    pAC->DynIrqModInfo.MaxModIntsPerSec);
634        } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
635             if (IsIntModEnabled(pAC)) {
636                printk("Dynamic int moderation runs with %i INTS/sec\n",
637                       pAC->DynIrqModInfo.MaxModIntsPerSec);
638             } else {
639                printk("Dynamic int moderation currently not applied\n");
640             }
641        } else {
642             printk("No interrupt moderation selected!\n");
643        }
644    }
645}
646
647/*******************************************************************************
648** Function     : DisplaySelectedModerationMask()
649** Description  : Displays what interrupts are moderated
650** Programmer   : Ralph Roesler
651** Last Modified: 23-mar-03
652** Returns      : void!
653** Notes        : -
654*******************************************************************************/
655
656static void
657DisplaySelectedModerationMask(SK_AC *pAC) {
658
659    if (pAC->DynIrqModInfo.DisplayStats) {
660        if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
661            switch (pAC->DynIrqModInfo.MaskIrqModeration) {
662                case IRQ_MASK_TX_ONLY:
663                   printk("Only Tx-interrupts are moderated\n");
664                   break;
665                case IRQ_MASK_RX_ONLY:
666                   printk("Only Rx-interrupts are moderated\n");
667                   break;
668                case IRQ_MASK_SP_ONLY:
669                   printk("Only special-interrupts are moderated\n");
670                   break;
671                case IRQ_MASK_TX_RX:
672                   printk("Tx- and Rx-interrupts are moderated\n");
673                   break;
674                case IRQ_MASK_SP_RX:
675                   printk("Special- and Rx-interrupts are moderated\n");
676                   break;
677                case IRQ_MASK_SP_TX:
678                   printk("Special- and Tx-interrupts are moderated\n");
679                   break;
680                case IRQ_MASK_RX_TX_SP:
681                   printk("All Rx-, Tx and special-interrupts are moderated\n");
682                   break;
683                default:
684                   printk("Don't know what is moderated\n");
685                   break;
686            }
687        } else {
688            printk("No specific interrupts masked for moderation\n");
689        }
690    }
691}
692
693/*******************************************************************************
694** Function     : DisplayDescrRatio
695** Description  : Like the name states...
696** Programmer   : Ralph Roesler
697** Last Modified: 23-mar-03
698** Returns      : void!
699** Notes        : -
700*******************************************************************************/
701
702static void
703DisplayDescrRatio(SK_AC *pAC) {
704    int TotalMaxNbrDescr = 0;
705
706    if (pAC->DynIrqModInfo.DisplayStats) {
707        TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
708        printk("Ratio descriptors: %i/%i\n",
709               M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
710    }
711}
712
713/*******************************************************************************
714**
715** End of file
716**
717*******************************************************************************/
718