Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /******************************************************************************
  2  *
  3  * Name:        skdim.c
  4  * Project:     GEnesis, PCI Gigabit Ethernet Adapter
  5  * Version:     $Revision: 1.5 $
  6  * Date:        $Date: 2003/11/28 12:55:40 $
  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
 40 static const char SysKonnectFileId[] =
 41         "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
 42 #endif
 43 
 44 #define __SKADDR_C
 45 
 46 #ifdef __cplusplus
 47 #error C++ is not yet supported.
 48 extern "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 
 85 static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
 86 static SK_U64       GetIsrCalls(SK_AC *pAC);
 87 static SK_BOOL      IsIntModEnabled(SK_AC *pAC);
 88 static void         SetCurrIntCtr(SK_AC *pAC);
 89 static void         EnableIntMod(SK_AC *pAC); 
 90 static void         DisableIntMod(SK_AC *pAC);
 91 static void         ResizeDimTimerDuration(SK_AC *pAC);
 92 static void         DisplaySelectedModerationType(SK_AC *pAC);
 93 static void         DisplaySelectedModerationMask(SK_AC *pAC);
 94 static 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 
124 void 
125 SkDimModerate(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 usefull
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 
214 void 
215 SkDimStartModerationTimer(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 
236 void
237 SkDimEnableModerationIfNeeded(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 regaring interrupt moderation
256 ** Programmer   : Ralph Roesler
257 ** Last Modified: 22-mar-03
258 ** Returns      : void (!)
259 ** Notes        : -
260 *******************************************************************************/
261 
262 void 
263 SkDimDisplayModerationSettings(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 
287 static unsigned int
288 GetCurrentSystemLoad(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         /*
301         ** The following lines have been commented out, because
302         ** from kernel 2.5.44 onwards, the kernel-owned structure
303         **
304         **      struct kernel_stat kstat
305         **
306         ** is not marked as an exported symbol in the file
307         **
308         **      kernel/ksyms.c 
309         **
310         ** As a consequence, using this driver as KLM is not possible
311         ** and any access of the structure kernel_stat via the 
312         ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.
313         **
314         ** The kstat-information might be added again in future 
315         ** versions of the 2.5.xx kernel, but for the time being, 
316         ** number of interrupts will serve as indication how much 
317         ** load we currently have... 
318         **
319         ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {
320         **      UserTime   = UserTime   + kstat_cpu(NbrCpu).cpustat.user;
321         **      NiceTime   = NiceTime   + kstat_cpu(NbrCpu).cpustat.nice;
322         **      SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;
323         ** }
324         */
325         SK_U64 ThresholdInts  = 0;
326         SK_U64 IsrCallsPerSec = 0;
327 
328         ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *
329                            C_INT_MOD_ENABLE_PERCENTAGE) + 100);
330         IsrCallsPerSec = GetIsrCalls(pAC);
331         if (IsrCallsPerSec >= ThresholdInts) {
332             /*
333             ** We do not know how much the real CPU-load is!
334             ** Return 80% as a default in order to activate DIM
335             */
336             SystemLoad = 80;
337             return (SystemLoad);  
338         } 
339 
340         UsedTime  = UserTime + NiceTime + SystemTime;
341 
342         IdleTime  = jif * num_online_cpus() - UsedTime;
343         TotalTime = UsedTime + IdleTime;
344 
345         SystemLoad = ( 100 * (UsedTime  - M_DIMINFO.PrevUsedTime) ) /
346                                                 (TotalTime - M_DIMINFO.PrevTotalTime);
347 
348         if (M_DIMINFO.DisplayStats) {
349                 printk("Current system load is: %u\n", SystemLoad);
350         }
351 
352         M_DIMINFO.PrevTotalTime = TotalTime;
353         M_DIMINFO.PrevUsedTime  = UsedTime;
354 
355         return (SystemLoad);
356 }
357 
358 /*******************************************************************************
359 ** Function     : GetIsrCalls
360 ** Description  : Depending on the selected moderation mask, this function will
361 **                return the number of interrupts handled in the previous time-
362 **                frame. This evaluated number is based on the current number 
363 **                of interrupts stored in PNMI-context and the previous stored 
364 **                interrupts.
365 ** Programmer   : Ralph Roesler
366 ** Last Modified: 23-mar-03
367 ** Returns      : int:   the number of interrupts being executed in the last
368 **                       timeframe
369 ** Notes        : It makes only sense to call this function, when dynamic 
370 **                interrupt moderation is applied
371 *******************************************************************************/
372 
373 static SK_U64
374 GetIsrCalls(SK_AC *pAC) {
375     SK_U64   RxPort0IntDiff = 0;
376     SK_U64   RxPort1IntDiff = 0;
377     SK_U64   TxPort0IntDiff = 0;
378     SK_U64   TxPort1IntDiff = 0;
379 
380     if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
381         if (pAC->GIni.GIMacsFound == 2) {
382             TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - 
383                              pAC->DynIrqModInfo.PrevPort1TxIntrCts;
384         }
385         TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
386                          pAC->DynIrqModInfo.PrevPort0TxIntrCts;
387     } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
388         if (pAC->GIni.GIMacsFound == 2) {
389             RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
390                              pAC->DynIrqModInfo.PrevPort1RxIntrCts;
391         }
392         RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
393                          pAC->DynIrqModInfo.PrevPort0RxIntrCts;
394     } else {
395         if (pAC->GIni.GIMacsFound == 2) {
396             RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
397                              pAC->DynIrqModInfo.PrevPort1RxIntrCts;
398             TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - 
399                              pAC->DynIrqModInfo.PrevPort1TxIntrCts;
400         } 
401         RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
402                          pAC->DynIrqModInfo.PrevPort0RxIntrCts;
403         TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
404                          pAC->DynIrqModInfo.PrevPort0TxIntrCts;
405     }
406 
407     return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
408 }
409 
410 /*******************************************************************************
411 ** Function     : GetRxCalls
412 ** Description  : This function will return the number of times a receive inter-
413 **                rupt was processed. This is needed to evaluate any resizing 
414 **                factor.
415 ** Programmer   : Ralph Roesler
416 ** Last Modified: 23-mar-03
417 ** Returns      : SK_U64: the number of RX-ints being processed
418 ** Notes        : It makes only sense to call this function, when dynamic 
419 **                interrupt moderation is applied
420 *******************************************************************************/
421 
422 static SK_U64
423 GetRxCalls(SK_AC *pAC) {
424     SK_U64   RxPort0IntDiff = 0;
425     SK_U64   RxPort1IntDiff = 0;
426 
427     if (pAC->GIni.GIMacsFound == 2) {
428         RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
429                          pAC->DynIrqModInfo.PrevPort1RxIntrCts;
430     }
431     RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
432                      pAC->DynIrqModInfo.PrevPort0RxIntrCts;
433 
434     return (RxPort0IntDiff + RxPort1IntDiff);
435 }
436 
437 /*******************************************************************************
438 ** Function     : SetCurrIntCtr
439 ** Description  : Will store the current number orf occured interrupts in the 
440 **                adapter context. This is needed to evaluated the number of 
441 **                interrupts within a current timeframe.
442 ** Programmer   : Ralph Roesler
443 ** Last Modified: 23-mar-03
444 ** Returns      : void (!)
445 ** Notes        : -
446 *******************************************************************************/
447 
448 static void
449 SetCurrIntCtr(SK_AC *pAC) {
450     if (pAC->GIni.GIMacsFound == 2) {
451         pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
452         pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
453     } 
454     pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
455     pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
456 }
457 
458 /*******************************************************************************
459 ** Function     : IsIntModEnabled()
460 ** Description  : Retrieves the current value of the interrupts moderation
461 **                command register. Its content determines whether any 
462 **                moderation is running or not.
463 ** Programmer   : Ralph Roesler
464 ** Last Modified: 23-mar-03
465 ** Returns      : SK_TRUE  : if mod timer running
466 **                SK_FALSE : if no moderation is being performed
467 ** Notes        : -
468 *******************************************************************************/
469 
470 static SK_BOOL
471 IsIntModEnabled(SK_AC *pAC) {
472     unsigned long CtrCmd;
473 
474     SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
475     if ((CtrCmd & TIM_START) == TIM_START) {
476        return SK_TRUE;
477     } else {
478        return SK_FALSE;
479     }
480 }
481 
482 /*******************************************************************************
483 ** Function     : EnableIntMod()
484 ** Description  : Enables the interrupt moderation using the values stored in
485 **                in the pAC->DynIntMod data structure
486 ** Programmer   : Ralph Roesler
487 ** Last Modified: 22-mar-03
488 ** Returns      : -
489 ** Notes        : -
490 *******************************************************************************/
491 
492 static void
493 EnableIntMod(SK_AC *pAC) {
494     unsigned long ModBase;
495 
496     if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
497        ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
498     } else {
499        ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
500     }
501 
502     SK_OUT32(pAC->IoBase, B2_IRQM_INI,  ModBase);
503     SK_OUT32(pAC->IoBase, B2_IRQM_MSK,  pAC->DynIrqModInfo.MaskIrqModeration);
504     SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
505     if (M_DIMINFO.DisplayStats) {
506         printk("Enabled interrupt moderation (%i ints/sec)\n",
507                M_DIMINFO.MaxModIntsPerSec);
508     }
509 }
510 
511 /*******************************************************************************
512 ** Function     : DisableIntMod()
513 ** Description  : Disbles the interrupt moderation independent of what inter-
514 **                rupts are running or not
515 ** Programmer   : Ralph Roesler
516 ** Last Modified: 23-mar-03
517 ** Returns      : -
518 ** Notes        : -
519 *******************************************************************************/
520 
521 static void 
522 DisableIntMod(SK_AC *pAC) {
523 
524     SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
525     if (M_DIMINFO.DisplayStats) {
526         printk("Disabled interrupt moderation\n");
527     }
528 } 
529 
530 /*******************************************************************************
531 ** Function     : ResizeDimTimerDuration();
532 ** Description  : Checks the current used descriptor ratio and resizes the 
533 **                duration timer (longer/smaller) if possible. 
534 ** Programmer   : Ralph Roesler
535 ** Last Modified: 23-mar-03
536 ** Returns      : -
537 ** Notes        : There are both maximum and minimum timer duration value. 
538 **                This function assumes that interrupt moderation is already
539 **                enabled!
540 *******************************************************************************/
541 
542 static void 
543 ResizeDimTimerDuration(SK_AC *pAC) {
544     SK_BOOL IncreaseTimerDuration;
545     int     TotalMaxNbrDescr;
546     int     UsedDescrRatio;
547     int     RatioDiffAbs;
548     int     RatioDiffRel;
549     int     NewMaxModIntsPerSec;
550     int     ModAdjValue;
551     long    ModBase;
552 
553     /*
554     ** Check first if we are allowed to perform any modification
555     */
556     if (IsIntModEnabled(pAC)) { 
557         if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
558             return; 
559         } else {
560             if (M_DIMINFO.ModJustEnabled) {
561                 M_DIMINFO.ModJustEnabled = SK_FALSE;
562                 return;
563             }
564         }
565     }
566 
567     /*
568     ** If we got until here, we have to evaluate the amount of the
569     ** descriptor ratio change...
570     */
571     TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
572     UsedDescrRatio   = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
573 
574     if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
575         RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
576         RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
577         M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
578         IncreaseTimerDuration = SK_FALSE;  /* in other words: DECREASE */
579     } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
580         RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
581         RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
582         M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
583         IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
584     } else {
585         RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
586         RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
587         M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
588         IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
589     }
590 
591     /*
592     ** Now we can determine the change in percent
593     */
594     if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
595        ModAdjValue = 1;  /*  1% change - maybe some other value in future */
596     } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
597        ModAdjValue = 1;  /*  1% change - maybe some other value in future */
598     } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
599        ModAdjValue = 1;  /*  1% change - maybe some other value in future */
600     } else {
601        ModAdjValue = 1;  /*  1% change - maybe some other value in future */
602     }
603 
604     if (IncreaseTimerDuration) {
605        NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec +
606                              (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
607     } else {
608        NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec -
609                              (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
610     }
611 
612     /* 
613     ** Check if we exceed boundaries...
614     */
615     if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
616          (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
617         if (M_DIMINFO.DisplayStats) {
618             printk("Cannot change ModTim from %i to %i ints/sec\n",
619                    M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
620         }
621         return;
622     } else {
623         if (M_DIMINFO.DisplayStats) {
624             printk("Resized ModTim from %i to %i ints/sec\n",
625                    M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
626         }
627     }
628 
629     M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
630 
631     if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
632         ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
633     } else {
634         ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
635     }
636 
637     /* 
638     ** We do not need to touch any other registers
639     */
640     SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
641 } 
642 
643 /*******************************************************************************
644 ** Function     : DisplaySelectedModerationType()
645 ** Description  : Displays what type of moderation we have
646 ** Programmer   : Ralph Roesler
647 ** Last Modified: 23-mar-03
648 ** Returns      : void!
649 ** Notes        : -
650 *******************************************************************************/
651 
652 static void
653 DisplaySelectedModerationType(SK_AC *pAC) {
654 
655     if (pAC->DynIrqModInfo.DisplayStats) {
656         if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
657              printk("Static int moderation runs with %i INTS/sec\n",
658                     pAC->DynIrqModInfo.MaxModIntsPerSec);
659         } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
660              if (IsIntModEnabled(pAC)) {
661                 printk("Dynamic int moderation runs with %i INTS/sec\n",
662                        pAC->DynIrqModInfo.MaxModIntsPerSec);
663              } else {
664                 printk("Dynamic int moderation currently not applied\n");
665              }
666         } else {
667              printk("No interrupt moderation selected!\n");
668         }
669     }
670 }
671 
672 /*******************************************************************************
673 ** Function     : DisplaySelectedModerationMask()
674 ** Description  : Displays what interrupts are moderated
675 ** Programmer   : Ralph Roesler
676 ** Last Modified: 23-mar-03
677 ** Returns      : void!
678 ** Notes        : -
679 *******************************************************************************/
680 
681 static void
682 DisplaySelectedModerationMask(SK_AC *pAC) {
683 
684     if (pAC->DynIrqModInfo.DisplayStats) {
685         if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
686             switch (pAC->DynIrqModInfo.MaskIrqModeration) {
687                 case IRQ_MASK_TX_ONLY: 
688                    printk("Only Tx-interrupts are moderated\n");
689                    break;
690                 case IRQ_MASK_RX_ONLY: 
691                    printk("Only Rx-interrupts are moderated\n");
692                    break;
693                 case IRQ_MASK_SP_ONLY: 
694                    printk("Only special-interrupts are moderated\n");
695                    break;
696                 case IRQ_MASK_TX_RX: 
697                    printk("Tx- and Rx-interrupts are moderated\n");
698                    break;
699                 case IRQ_MASK_SP_RX: 
700                    printk("Special- and Rx-interrupts are moderated\n");
701                    break;
702                 case IRQ_MASK_SP_TX: 
703                    printk("Special- and Tx-interrupts are moderated\n");
704                    break;
705                 case IRQ_MASK_RX_TX_SP:
706                    printk("All Rx-, Tx and special-interrupts are moderated\n");
707                    break;
708                 default:
709                    printk("Don't know what is moderated\n");
710                    break;
711             }
712         } else {
713             printk("No specific interrupts masked for moderation\n");
714         }
715     } 
716 }
717 
718 /*******************************************************************************
719 ** Function     : DisplayDescrRatio
720 ** Description  : Like the name states...
721 ** Programmer   : Ralph Roesler
722 ** Last Modified: 23-mar-03
723 ** Returns      : void!
724 ** Notes        : -
725 *******************************************************************************/
726 
727 static void
728 DisplayDescrRatio(SK_AC *pAC) {
729     int TotalMaxNbrDescr = 0;
730 
731     if (pAC->DynIrqModInfo.DisplayStats) {
732         TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
733         printk("Ratio descriptors: %i/%i\n",
734                M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
735     }
736 }
737 
738 /*******************************************************************************
739 **
740 ** End of file
741 **
742 *******************************************************************************/
743 
  This page was automatically generated by the LXR engine.