aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2010-05-04 18:26:03 -0400
committerDavid S. Miller <davem@davemloft.net>2010-05-06 00:15:32 -0400
commiteab2abf5826b78b126826cc70e564c44816396da (patch)
treef771389b55090767e8aecdc36f3e80019b3b60bf /drivers
parentedf15c17420fed108046da50b3d3ae53dfa0e0ae (diff)
e1000/e1000e: implement a simple interrupt moderation
Back before e1000-7.3.20, the e1000 driver had a simple algorithm that managed interrupt moderation. The driver was updated in 7.3.20 to have the new "adaptive" interrupt moderation but we have customer requests to redeploy the old way as an option. This patch adds the old functionality back. The new functionality can be enabled via module parameter or at runtime via ethtool. Module parameter: (InterruptThrottleRate=4) to use this new moderation method. Ethtool method: ethtool -C ethX rx-usecs 4 Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/e1000/e1000_ethtool.c8
-rw-r--r--drivers/net/e1000/e1000_main.c18
-rw-r--r--drivers/net/e1000/e1000_param.c10
-rw-r--r--drivers/net/e1000e/ethtool.c8
-rw-r--r--drivers/net/e1000e/netdev.c18
-rw-r--r--drivers/net/e1000e/param.c5
6 files changed, 57 insertions, 10 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index d6931cabe421..2a3b2dccd06d 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1808,7 +1808,7 @@ static int e1000_get_coalesce(struct net_device *netdev,
1808 if (adapter->hw.mac_type < e1000_82545) 1808 if (adapter->hw.mac_type < e1000_82545)
1809 return -EOPNOTSUPP; 1809 return -EOPNOTSUPP;
1810 1810
1811 if (adapter->itr_setting <= 3) 1811 if (adapter->itr_setting <= 4)
1812 ec->rx_coalesce_usecs = adapter->itr_setting; 1812 ec->rx_coalesce_usecs = adapter->itr_setting;
1813 else 1813 else
1814 ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting; 1814 ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
@@ -1826,12 +1826,14 @@ static int e1000_set_coalesce(struct net_device *netdev,
1826 return -EOPNOTSUPP; 1826 return -EOPNOTSUPP;
1827 1827
1828 if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) || 1828 if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) ||
1829 ((ec->rx_coalesce_usecs > 3) && 1829 ((ec->rx_coalesce_usecs > 4) &&
1830 (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) || 1830 (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) ||
1831 (ec->rx_coalesce_usecs == 2)) 1831 (ec->rx_coalesce_usecs == 2))
1832 return -EINVAL; 1832 return -EINVAL;
1833 1833
1834 if (ec->rx_coalesce_usecs <= 3) { 1834 if (ec->rx_coalesce_usecs == 4) {
1835 adapter->itr = adapter->itr_setting = 4;
1836 } else if (ec->rx_coalesce_usecs <= 3) {
1835 adapter->itr = 20000; 1837 adapter->itr = 20000;
1836 adapter->itr_setting = ec->rx_coalesce_usecs; 1838 adapter->itr_setting = ec->rx_coalesce_usecs;
1837 } else { 1839 } else {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index e6ebc222459f..4dd2c23775cb 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -31,7 +31,7 @@
31 31
32char e1000_driver_name[] = "e1000"; 32char e1000_driver_name[] = "e1000";
33static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; 33static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
34#define DRV_VERSION "7.3.21-k5-NAPI" 34#define DRV_VERSION "7.3.21-k6-NAPI"
35const char e1000_driver_version[] = DRV_VERSION; 35const char e1000_driver_version[] = DRV_VERSION;
36static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; 36static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
37 37
@@ -2386,6 +2386,22 @@ link_up:
2386 } 2386 }
2387 } 2387 }
2388 2388
2389 /* Simple mode for Interrupt Throttle Rate (ITR) */
2390 if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
2391 /*
2392 * Symmetric Tx/Rx gets a reduced ITR=2000;
2393 * Total asymmetrical Tx or Rx gets ITR=8000;
2394 * everyone else is between 2000-8000.
2395 */
2396 u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
2397 u32 dif = (adapter->gotcl > adapter->gorcl ?
2398 adapter->gotcl - adapter->gorcl :
2399 adapter->gorcl - adapter->gotcl) / 10000;
2400 u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
2401
2402 ew32(ITR, 1000000000 / (itr * 256));
2403 }
2404
2389 /* Cause software interrupt to ensure rx ring is cleaned */ 2405 /* Cause software interrupt to ensure rx ring is cleaned */
2390 ew32(ICS, E1000_ICS_RXDMT0); 2406 ew32(ICS, E1000_ICS_RXDMT0);
2391 2407
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 543c6d1767bc..9fbb562dc964 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -484,11 +484,17 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
484 adapter->itr_setting = adapter->itr; 484 adapter->itr_setting = adapter->itr;
485 adapter->itr = 20000; 485 adapter->itr = 20000;
486 break; 486 break;
487 case 4:
488 e_dev_info("%s set to simplified "
489 "(2000-8000) ints mode\n", opt.name);
490 adapter->itr_setting = adapter->itr;
491 break;
487 default: 492 default:
488 e1000_validate_option(&adapter->itr, &opt, 493 e1000_validate_option(&adapter->itr, &opt,
489 adapter); 494 adapter);
490 /* save the setting, because the dynamic bits change itr */ 495 /* save the setting, because the dynamic bits
491 /* clear the lower two bits because they are 496 * change itr.
497 * clear the lower two bits because they are
492 * used as control */ 498 * used as control */
493 adapter->itr_setting = adapter->itr & ~3; 499 adapter->itr_setting = adapter->itr & ~3;
494 break; 500 break;
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index b72c1c0876fc..6ff376cfe139 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1890,7 +1890,7 @@ static int e1000_get_coalesce(struct net_device *netdev,
1890{ 1890{
1891 struct e1000_adapter *adapter = netdev_priv(netdev); 1891 struct e1000_adapter *adapter = netdev_priv(netdev);
1892 1892
1893 if (adapter->itr_setting <= 3) 1893 if (adapter->itr_setting <= 4)
1894 ec->rx_coalesce_usecs = adapter->itr_setting; 1894 ec->rx_coalesce_usecs = adapter->itr_setting;
1895 else 1895 else
1896 ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting; 1896 ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
@@ -1905,12 +1905,14 @@ static int e1000_set_coalesce(struct net_device *netdev,
1905 struct e1000_hw *hw = &adapter->hw; 1905 struct e1000_hw *hw = &adapter->hw;
1906 1906
1907 if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) || 1907 if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) ||
1908 ((ec->rx_coalesce_usecs > 3) && 1908 ((ec->rx_coalesce_usecs > 4) &&
1909 (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) || 1909 (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) ||
1910 (ec->rx_coalesce_usecs == 2)) 1910 (ec->rx_coalesce_usecs == 2))
1911 return -EINVAL; 1911 return -EINVAL;
1912 1912
1913 if (ec->rx_coalesce_usecs <= 3) { 1913 if (ec->rx_coalesce_usecs == 4) {
1914 adapter->itr = adapter->itr_setting = 4;
1915 } else if (ec->rx_coalesce_usecs <= 3) {
1914 adapter->itr = 20000; 1916 adapter->itr = 20000;
1915 adapter->itr_setting = ec->rx_coalesce_usecs; 1917 adapter->itr_setting = ec->rx_coalesce_usecs;
1916 } else { 1918 } else {
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 478c34a47d18..c5f65a29865a 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -52,7 +52,7 @@
52 52
53#include "e1000.h" 53#include "e1000.h"
54 54
55#define DRV_VERSION "1.0.2-k2" 55#define DRV_VERSION "1.0.2-k4"
56char e1000e_driver_name[] = "e1000e"; 56char e1000e_driver_name[] = "e1000e";
57const char e1000e_driver_version[] = DRV_VERSION; 57const char e1000e_driver_version[] = DRV_VERSION;
58 58
@@ -4070,6 +4070,22 @@ link_up:
4070 } 4070 }
4071 } 4071 }
4072 4072
4073 /* Simple mode for Interrupt Throttle Rate (ITR) */
4074 if (adapter->itr_setting == 4) {
4075 /*
4076 * Symmetric Tx/Rx gets a reduced ITR=2000;
4077 * Total asymmetrical Tx or Rx gets ITR=8000;
4078 * everyone else is between 2000-8000.
4079 */
4080 u32 goc = (adapter->gotc + adapter->gorc) / 10000;
4081 u32 dif = (adapter->gotc > adapter->gorc ?
4082 adapter->gotc - adapter->gorc :
4083 adapter->gorc - adapter->gotc) / 10000;
4084 u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
4085
4086 ew32(ITR, 1000000000 / (itr * 256));
4087 }
4088
4073 /* Cause software interrupt to ensure Rx ring is cleaned */ 4089 /* Cause software interrupt to ensure Rx ring is cleaned */
4074 if (adapter->msix_entries) 4090 if (adapter->msix_entries)
4075 ew32(ICS, adapter->rx_ring->ims_val); 4091 ew32(ICS, adapter->rx_ring->ims_val);
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index f775a481063d..0f4077c3d538 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -351,6 +351,11 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
351 adapter->itr_setting = adapter->itr; 351 adapter->itr_setting = adapter->itr;
352 adapter->itr = 20000; 352 adapter->itr = 20000;
353 break; 353 break;
354 case 4:
355 e_info("%s set to simplified (2000-8000 ints) "
356 "mode\n", opt.name);
357 adapter->itr_setting = 4;
358 break;
354 default: 359 default:
355 /* 360 /*
356 * Save the setting, because the dynamic bits 361 * Save the setting, because the dynamic bits