e1000: allow ethtool coalesece to adjust interrupts per second
This patch allows on-the-fly adjustment of the interrupts per second generated by e1000 devices 82545/82546 (hardware support of ITR register is a requirement) adjust using this command: ethtool -C eth0 rx-usecs 10 where 10 is 10 microseconds per interrupt interval, so 10 = 100,000 interrupts per second, and 125 = 8000 interrupts per second. changes should be immediate. 1,3 are special values and indicate the automatic tuning mode to the driver, where 1 is 4000-90000 interrupts per second and 3 is 4000-20000 interrupts per second and is the driver default. 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>
This commit is contained in:
parent
f77139c07a
commit
94c9e5a893
|
@ -111,6 +111,9 @@ do { \
|
|||
#define E1000_MIN_RXD 80
|
||||
#define E1000_MAX_82544_RXD 4096
|
||||
|
||||
#define E1000_MIN_ITR_USECS 10 /* 100000 irq/sec */
|
||||
#define E1000_MAX_ITR_USECS 10000 /* 100 irq/sec */
|
||||
|
||||
/* this is the size past which hardware will drop packets when setting LPE=0 */
|
||||
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
|
||||
|
||||
|
|
|
@ -1904,6 +1904,53 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int e1000_get_coalesce(struct net_device *netdev,
|
||||
struct ethtool_coalesce *ec)
|
||||
{
|
||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
if (adapter->hw.mac_type < e1000_82545)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (adapter->itr_setting <= 3)
|
||||
ec->rx_coalesce_usecs = adapter->itr_setting;
|
||||
else
|
||||
ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int e1000_set_coalesce(struct net_device *netdev,
|
||||
struct ethtool_coalesce *ec)
|
||||
{
|
||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
|
||||
if (hw->mac_type < e1000_82545)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) ||
|
||||
((ec->rx_coalesce_usecs > 3) &&
|
||||
(ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) ||
|
||||
(ec->rx_coalesce_usecs == 2))
|
||||
return -EINVAL;
|
||||
|
||||
if (ec->rx_coalesce_usecs <= 3) {
|
||||
adapter->itr = 20000;
|
||||
adapter->itr_setting = ec->rx_coalesce_usecs;
|
||||
} else {
|
||||
adapter->itr = (1000000 / ec->rx_coalesce_usecs);
|
||||
adapter->itr_setting = adapter->itr & ~3;
|
||||
}
|
||||
|
||||
if (adapter->itr_setting != 0)
|
||||
ew32(ITR, 1000000000 / (adapter->itr * 256));
|
||||
else
|
||||
ew32(ITR, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int e1000_nway_reset(struct net_device *netdev)
|
||||
{
|
||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
|
@ -1978,7 +2025,9 @@ static const struct ethtool_ops e1000_ethtool_ops = {
|
|||
.get_strings = e1000_get_strings,
|
||||
.phys_id = e1000_phys_id,
|
||||
.get_ethtool_stats = e1000_get_ethtool_stats,
|
||||
.get_sset_count = e1000_get_sset_count,
|
||||
.get_sset_count = e1000_get_sset_count,
|
||||
.get_coalesce = e1000_get_coalesce,
|
||||
.set_coalesce = e1000_set_coalesce,
|
||||
};
|
||||
|
||||
void e1000_set_ethtool_ops(struct net_device *netdev)
|
||||
|
|
Loading…
Reference in New Issue