]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/e1000e/netdev.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[karo-tx-linux.git] / drivers / net / e1000e / netdev.c
index 6d513a383340c17c21b6c210e881c70189bc9012..a39d4a4d871c2aac2c3fd2a662924b44ed9eb011 100644 (file)
@@ -54,7 +54,7 @@
 
 #define DRV_EXTRAVERSION "-k2"
 
-#define DRV_VERSION "1.2.20" DRV_EXTRAVERSION
+#define DRV_VERSION "1.3.10" DRV_EXTRAVERSION
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -900,8 +900,6 @@ next_desc:
 
        adapter->total_rx_bytes += total_rx_bytes;
        adapter->total_rx_packets += total_rx_packets;
-       netdev->stats.rx_bytes += total_rx_bytes;
-       netdev->stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -1060,8 +1058,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
        }
        adapter->total_tx_bytes += total_tx_bytes;
        adapter->total_tx_packets += total_tx_packets;
-       netdev->stats.tx_bytes += total_tx_bytes;
-       netdev->stats.tx_packets += total_tx_packets;
        return count < tx_ring->count;
 }
 
@@ -1248,8 +1244,6 @@ next_desc:
 
        adapter->total_rx_bytes += total_rx_bytes;
        adapter->total_rx_packets += total_rx_packets;
-       netdev->stats.rx_bytes += total_rx_bytes;
-       netdev->stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -1328,7 +1322,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
                                /* an error means any chain goes out the window
                                 * too */
                                if (rx_ring->rx_skb_top)
-                                       dev_kfree_skb(rx_ring->rx_skb_top);
+                                       dev_kfree_skb_irq(rx_ring->rx_skb_top);
                                rx_ring->rx_skb_top = NULL;
                                goto next_desc;
                }
@@ -1401,7 +1395,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
                /* eth type trans needs skb->data to point to something */
                if (!pskb_may_pull(skb, ETH_HLEN)) {
                        e_err("pskb_may_pull failed.\n");
-                       dev_kfree_skb(skb);
+                       dev_kfree_skb_irq(skb);
                        goto next_desc;
                }
 
@@ -1429,8 +1423,6 @@ next_desc:
 
        adapter->total_rx_bytes += total_rx_bytes;
        adapter->total_rx_packets += total_rx_packets;
-       netdev->stats.rx_bytes += total_rx_bytes;
-       netdev->stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -1857,7 +1849,9 @@ static int e1000_request_msix(struct e1000_adapter *adapter)
        int err = 0, vector = 0;
 
        if (strlen(netdev->name) < (IFNAMSIZ - 5))
-               sprintf(adapter->rx_ring->name, "%s-rx-0", netdev->name);
+               snprintf(adapter->rx_ring->name,
+                        sizeof(adapter->rx_ring->name) - 1,
+                        "%s-rx-0", netdev->name);
        else
                memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
        err = request_irq(adapter->msix_entries[vector].vector,
@@ -1870,7 +1864,9 @@ static int e1000_request_msix(struct e1000_adapter *adapter)
        vector++;
 
        if (strlen(netdev->name) < (IFNAMSIZ - 5))
-               sprintf(adapter->tx_ring->name, "%s-tx-0", netdev->name);
+               snprintf(adapter->tx_ring->name,
+                        sizeof(adapter->tx_ring->name) - 1,
+                        "%s-tx-0", netdev->name);
        else
                memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
        err = request_irq(adapter->msix_entries[vector].vector,
@@ -2734,7 +2730,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        u32 rctl, rfctl;
-       u32 psrctl = 0;
        u32 pages = 0;
 
        /* Workaround Si errata on 82579 - configure jumbo frame flow */
@@ -2833,6 +2828,8 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
                adapter->rx_ps_pages = 0;
 
        if (adapter->rx_ps_pages) {
+               u32 psrctl = 0;
+
                /* Configure extra packet-split registers */
                rfctl = er32(RFCTL);
                rfctl |= E1000_RFCTL_EXTEN;
@@ -3034,7 +3031,6 @@ static void e1000_set_multi(struct net_device *netdev)
        struct netdev_hw_addr *ha;
        u8  *mta_list;
        u32 rctl;
-       int i;
 
        /* Check for Promiscuous and All Multicast modes */
 
@@ -3057,12 +3053,13 @@ static void e1000_set_multi(struct net_device *netdev)
        ew32(RCTL, rctl);
 
        if (!netdev_mc_empty(netdev)) {
+               int i = 0;
+
                mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC);
                if (!mta_list)
                        return;
 
                /* prepare a packed array of only addresses. */
-               i = 0;
                netdev_for_each_mc_addr(ha, netdev)
                        memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN);
 
@@ -3359,6 +3356,8 @@ static void e1000e_flush_descriptors(struct e1000_adapter *adapter)
        e1e_flush();
 }
 
+static void e1000e_update_stats(struct e1000_adapter *adapter);
+
 void e1000e_down(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
@@ -3393,6 +3392,11 @@ void e1000e_down(struct e1000_adapter *adapter)
        del_timer_sync(&adapter->phy_info_timer);
 
        netif_carrier_off(netdev);
+
+       spin_lock(&adapter->stats64_lock);
+       e1000e_update_stats(adapter);
+       spin_unlock(&adapter->stats64_lock);
+
        adapter->link_speed = 0;
        adapter->link_duplex = 0;
 
@@ -3437,6 +3441,8 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
        adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
        adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
 
+       spin_lock_init(&adapter->stats64_lock);
+
        e1000e_set_interrupt_capability(adapter);
 
        if (e1000_alloc_queues(adapter))
@@ -3918,7 +3924,7 @@ release:
  * e1000e_update_stats - Update the board statistics counters
  * @adapter: board private structure
  **/
-void e1000e_update_stats(struct e1000_adapter *adapter)
+static void e1000e_update_stats(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
        struct e1000_hw *hw = &adapter->hw;
@@ -4030,10 +4036,11 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        struct e1000_phy_regs *phy = &adapter->phy_regs;
-       int ret_val;
 
        if ((er32(STATUS) & E1000_STATUS_LU) &&
            (adapter->hw.phy.media_type == e1000_media_type_copper)) {
+               int ret_val;
+
                ret_val  = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr);
                ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr);
                ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise);
@@ -4179,7 +4186,6 @@ static void e1000_watchdog_task(struct work_struct *work)
        struct e1000_ring *tx_ring = adapter->tx_ring;
        struct e1000_hw *hw = &adapter->hw;
        u32 link, tctl;
-       int tx_pending = 0;
 
        if (test_bit(__E1000_DOWN, &adapter->state))
                return;
@@ -4320,7 +4326,9 @@ static void e1000_watchdog_task(struct work_struct *work)
        }
 
 link_up:
+       spin_lock(&adapter->stats64_lock);
        e1000e_update_stats(adapter);
+       spin_unlock(&adapter->stats64_lock);
 
        mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
        adapter->tpt_old = adapter->stats.tpt;
@@ -4334,20 +4342,17 @@ link_up:
 
        e1000e_update_adaptive(&adapter->hw);
 
-       if (!netif_carrier_ok(netdev)) {
-               tx_pending = (e1000_desc_unused(tx_ring) + 1 <
-                              tx_ring->count);
-               if (tx_pending) {
-                       /*
-                        * We've lost link, so the controller stops DMA,
-                        * but we've got queued Tx work that's never going
-                        * to get done, so reset controller to flush Tx.
-                        * (Do the reset outside of interrupt context).
-                        */
-                       schedule_work(&adapter->reset_task);
-                       /* return immediately since reset is imminent */
-                       return;
-               }
+       if (!netif_carrier_ok(netdev) &&
+           (e1000_desc_unused(tx_ring) + 1 < tx_ring->count)) {
+               /*
+                * We've lost link, so the controller stops DMA,
+                * but we've got queued Tx work that's never going
+                * to get done, so reset controller to flush Tx.
+                * (Do the reset outside of interrupt context).
+                */
+               schedule_work(&adapter->reset_task);
+               /* return immediately since reset is imminent */
+               return;
        }
 
        /* Simple mode for Interrupt Throttle Rate (ITR) */
@@ -4411,13 +4416,13 @@ static int e1000_tso(struct e1000_adapter *adapter,
        u32 cmd_length = 0;
        u16 ipcse = 0, tucse, mss;
        u8 ipcss, ipcso, tucss, tucso, hdr_len;
-       int err;
 
        if (!skb_is_gso(skb))
                return 0;
 
        if (skb_header_cloned(skb)) {
-               err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+               int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+
                if (err)
                        return err;
        }
@@ -4928,16 +4933,55 @@ static void e1000_reset_task(struct work_struct *work)
 }
 
 /**
- * e1000_get_stats - Get System Network Statistics
+ * e1000_get_stats64 - Get System Network Statistics
  * @netdev: network interface device structure
+ * @stats: rtnl_link_stats64 pointer
  *
  * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
  **/
-static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
+struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
+                                             struct rtnl_link_stats64 *stats)
 {
-       /* only return the current stats */
-       return &netdev->stats;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+
+       memset(stats, 0, sizeof(struct rtnl_link_stats64));
+       spin_lock(&adapter->stats64_lock);
+       e1000e_update_stats(adapter);
+       /* Fill out the OS statistics structure */
+       stats->rx_bytes = adapter->stats.gorc;
+       stats->rx_packets = adapter->stats.gprc;
+       stats->tx_bytes = adapter->stats.gotc;
+       stats->tx_packets = adapter->stats.gptc;
+       stats->multicast = adapter->stats.mprc;
+       stats->collisions = adapter->stats.colc;
+
+       /* Rx Errors */
+
+       /*
+        * RLEC on some newer hardware can be incorrect so build
+        * our own version based on RUC and ROC
+        */
+       stats->rx_errors = adapter->stats.rxerrc +
+               adapter->stats.crcerrs + adapter->stats.algnerrc +
+               adapter->stats.ruc + adapter->stats.roc +
+               adapter->stats.cexterr;
+       stats->rx_length_errors = adapter->stats.ruc +
+                                             adapter->stats.roc;
+       stats->rx_crc_errors = adapter->stats.crcerrs;
+       stats->rx_frame_errors = adapter->stats.algnerrc;
+       stats->rx_missed_errors = adapter->stats.mpc;
+
+       /* Tx Errors */
+       stats->tx_errors = adapter->stats.ecol +
+                                      adapter->stats.latecol;
+       stats->tx_aborted_errors = adapter->stats.ecol;
+       stats->tx_window_errors = adapter->stats.latecol;
+       stats->tx_carrier_errors = adapter->stats.tncrs;
+
+       /* Tx Dropped needs to be maintained elsewhere */
+
+       spin_unlock(&adapter->stats64_lock);
+       return stats;
 }
 
 /**
@@ -5507,9 +5551,10 @@ static irqreturn_t e1000_intr_msix(int irq, void *data)
 {
        struct net_device *netdev = data;
        struct e1000_adapter *adapter = netdev_priv(netdev);
-       int vector, msix_irq;
 
        if (adapter->msix_entries) {
+               int vector, msix_irq;
+
                vector = 0;
                msix_irq = adapter->msix_entries[vector].vector;
                disable_irq(msix_irq);
@@ -5706,7 +5751,7 @@ static const struct net_device_ops e1000e_netdev_ops = {
        .ndo_open               = e1000_open,
        .ndo_stop               = e1000_close,
        .ndo_start_xmit         = e1000_xmit_frame,
-       .ndo_get_stats          = e1000_get_stats,
+       .ndo_get_stats64        = e1000e_get_stats64,
        .ndo_set_multicast_list = e1000_set_multi,
        .ndo_set_mac_address    = e1000_set_mac,
        .ndo_change_mtu         = e1000_change_mtu,