|
@@ -1975,6 +1975,41 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * this function must be called before setting the new value of
|
|
|
+ * rx_itr_setting
|
|
|
+ */
|
|
|
+static bool ixgbe_update_rsc(struct ixgbe_adapter *adapter,
|
|
|
+ struct ethtool_coalesce *ec)
|
|
|
+{
|
|
|
+ struct net_device *netdev = adapter->netdev;
|
|
|
+
|
|
|
+ if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ /* if interrupt rate is too high then disable RSC */
|
|
|
+ if (ec->rx_coalesce_usecs != 1 &&
|
|
|
+ ec->rx_coalesce_usecs <= 1000000/IXGBE_MAX_RSC_INT_RATE) {
|
|
|
+ if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
|
|
|
+ e_info(probe, "rx-usecs set too low, "
|
|
|
+ "disabling RSC\n");
|
|
|
+ adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ /* check the feature flag value and enable RSC if necessary */
|
|
|
+ if ((netdev->features & NETIF_F_LRO) &&
|
|
|
+ !(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) {
|
|
|
+ e_info(probe, "rx-usecs set to %d, "
|
|
|
+ "re-enabling RSC\n",
|
|
|
+ ec->rx_coalesce_usecs);
|
|
|
+ adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
static int ixgbe_set_coalesce(struct net_device *netdev,
|
|
|
struct ethtool_coalesce *ec)
|
|
|
{
|
|
@@ -1992,17 +2027,14 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
|
|
|
adapter->tx_ring[0]->work_limit = ec->tx_max_coalesced_frames_irq;
|
|
|
|
|
|
if (ec->rx_coalesce_usecs > 1) {
|
|
|
- u32 max_int;
|
|
|
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
|
|
|
- max_int = IXGBE_MAX_RSC_INT_RATE;
|
|
|
- else
|
|
|
- max_int = IXGBE_MAX_INT_RATE;
|
|
|
-
|
|
|
/* check the limits */
|
|
|
- if ((1000000/ec->rx_coalesce_usecs > max_int) ||
|
|
|
+ if ((1000000/ec->rx_coalesce_usecs > IXGBE_MAX_INT_RATE) ||
|
|
|
(1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE))
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ /* check the old value and enable RSC if necessary */
|
|
|
+ need_reset = ixgbe_update_rsc(adapter, ec);
|
|
|
+
|
|
|
/* store the value in ints/second */
|
|
|
adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs;
|
|
|
|
|
@@ -2011,32 +2043,21 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
|
|
|
/* clear the lower bit as its used for dynamic state */
|
|
|
adapter->rx_itr_setting &= ~1;
|
|
|
} else if (ec->rx_coalesce_usecs == 1) {
|
|
|
+ /* check the old value and enable RSC if necessary */
|
|
|
+ need_reset = ixgbe_update_rsc(adapter, ec);
|
|
|
+
|
|
|
/* 1 means dynamic mode */
|
|
|
adapter->rx_eitr_param = 20000;
|
|
|
adapter->rx_itr_setting = 1;
|
|
|
} else {
|
|
|
+ /* check the old value and enable RSC if necessary */
|
|
|
+ need_reset = ixgbe_update_rsc(adapter, ec);
|
|
|
/*
|
|
|
* any other value means disable eitr, which is best
|
|
|
* served by setting the interrupt rate very high
|
|
|
*/
|
|
|
adapter->rx_eitr_param = IXGBE_MAX_INT_RATE;
|
|
|
adapter->rx_itr_setting = 0;
|
|
|
-
|
|
|
- /*
|
|
|
- * if hardware RSC is enabled, disable it when
|
|
|
- * setting low latency mode, to avoid errata, assuming
|
|
|
- * that when the user set low latency mode they want
|
|
|
- * it at the cost of anything else
|
|
|
- */
|
|
|
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
|
|
|
- adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
|
|
|
- if (netdev->features & NETIF_F_LRO) {
|
|
|
- netdev->features &= ~NETIF_F_LRO;
|
|
|
- e_info(probe, "rx-usecs set to 0, "
|
|
|
- "disabling RSC\n");
|
|
|
- }
|
|
|
- need_reset = true;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
if (ec->tx_coalesce_usecs > 1) {
|
|
@@ -2123,15 +2144,15 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
|
|
|
return rc;
|
|
|
|
|
|
/* if state changes we need to update adapter->flags and reset */
|
|
|
- if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) {
|
|
|
- /*
|
|
|
- * cast both to bool and verify if they are set the same
|
|
|
- * but only enable RSC if itr is non-zero, as
|
|
|
- * itr=0 and RSC are mutually exclusive
|
|
|
- */
|
|
|
- if (((!!(data & ETH_FLAG_LRO)) !=
|
|
|
- (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) &&
|
|
|
- adapter->rx_itr_setting) {
|
|
|
+ if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) &&
|
|
|
+ (!!(data & ETH_FLAG_LRO) !=
|
|
|
+ !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) {
|
|
|
+ if ((data & ETH_FLAG_LRO) &&
|
|
|
+ (!adapter->rx_itr_setting ||
|
|
|
+ (adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE))) {
|
|
|
+ e_info(probe, "rx-usecs set too low, "
|
|
|
+ "not enabling RSC.\n");
|
|
|
+ } else {
|
|
|
adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED;
|
|
|
switch (adapter->hw.mac.type) {
|
|
|
case ixgbe_mac_82599EB:
|
|
@@ -2140,11 +2161,6 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
- } else if (!adapter->rx_itr_setting) {
|
|
|
- netdev->features &= ~NETIF_F_LRO;
|
|
|
- if (data & ETH_FLAG_LRO)
|
|
|
- e_info(probe, "rx-usecs set to 0, "
|
|
|
- "LRO/RSC cannot be enabled.\n");
|
|
|
}
|
|
|
}
|
|
|
|