Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 77b2555b52a894a2e39a42e43d993df875c46a6a 742 lines 28 kB view raw
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 40static 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. 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 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 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 regaring 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 /* 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 373static SK_U64 374GetIsrCalls(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 422static SK_U64 423GetRxCalls(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 448static void 449SetCurrIntCtr(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 470static SK_BOOL 471IsIntModEnabled(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 492static void 493EnableIntMod(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 521static void 522DisableIntMod(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 542static void 543ResizeDimTimerDuration(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 652static void 653DisplaySelectedModerationType(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 681static void 682DisplaySelectedModerationMask(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 727static void 728DisplayDescrRatio(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*******************************************************************************/