📄 skdim.c
字号:
static SK_U64GetIsrCalls(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_U64GetRxCalls(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 voidSetCurrIntCtr(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_BOOLIsIntModEnabled(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 voidEnableIntMod(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 voidDisplaySelectedModerationType(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 voidDisplaySelectedModerationMask(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 voidDisplayDescrRatio(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*********************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -