]> err.no Git - linux-2.6/blobdiff - drivers/net/igb/igb_ethtool.c
igb: fixes 82576 serdes init to correctly support manual flow control changes
[linux-2.6] / drivers / net / igb / igb_ethtool.c
index ef209b5cd3908c04aa91f555b26c138ded9cf6e3..11aee13099513bea5dddd87cb4ff17fa4c135f7b 100644 (file)
@@ -93,6 +93,11 @@ static const struct igb_stats igb_gstrings_stats[] = {
        { "tx_smbus", IGB_STAT(stats.mgptc) },
        { "rx_smbus", IGB_STAT(stats.mgprc) },
        { "dropped_smbus", IGB_STAT(stats.mgpdc) },
+#ifdef CONFIG_IGB_LRO
+       { "lro_aggregated", IGB_STAT(lro_aggregated) },
+       { "lro_flushed", IGB_STAT(lro_flushed) },
+       { "lro_no_desc", IGB_STAT(lro_no_desc) },
+#endif
 };
 
 #define IGB_QUEUE_STATS_LEN \
@@ -1856,6 +1861,8 @@ static int igb_set_coalesce(struct net_device *netdev,
                            struct ethtool_coalesce *ec)
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       int i;
 
        if ((ec->rx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
            ((ec->rx_coalesce_usecs > 3) &&
@@ -1864,13 +1871,16 @@ static int igb_set_coalesce(struct net_device *netdev,
                return -EINVAL;
 
        /* convert to rate of irq's per second */
-       if (ec->rx_coalesce_usecs <= 3)
+       if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
                adapter->itr_setting = ec->rx_coalesce_usecs;
-       else
-               adapter->itr_setting = (1000000 / ec->rx_coalesce_usecs);
+               adapter->itr = IGB_START_ITR;
+       } else {
+               adapter->itr_setting = ec->rx_coalesce_usecs << 2;
+               adapter->itr = adapter->itr_setting;
+       }
 
-       if (netif_running(netdev))
-               igb_reinit_locked(adapter);
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               wr32(adapter->rx_ring[i].itr_register, adapter->itr);
 
        return 0;
 }
@@ -1883,7 +1893,7 @@ static int igb_get_coalesce(struct net_device *netdev,
        if (adapter->itr_setting <= 3)
                ec->rx_coalesce_usecs = adapter->itr_setting;
        else
-               ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
+               ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
 
        return 0;
 }
@@ -1917,6 +1927,18 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
        int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64);
        int j;
        int i;
+#ifdef CONFIG_IGB_LRO
+       int aggregated = 0, flushed = 0, no_desc = 0;
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
+               flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
+               no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
+       }
+       adapter->lro_aggregated = aggregated;
+       adapter->lro_flushed = flushed;
+       adapter->lro_no_desc = no_desc;
+#endif
 
        igb_update_stats(adapter);
        for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {