Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
[sfrench/cifs-2.6.git] / drivers / net / e1000e / netdev.c
index 57a7e41da69e91e64d547362d04c7495d907f567..521c6ee1f32af75a0abb5950d10c941376d60116 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -52,7 +52,9 @@
 
 #include "e1000.h"
 
-#define DRV_VERSION "1.0.2-k4"
+#define DRV_EXTRAVERSION "-k2"
+
+#define DRV_VERSION "1.2.7" DRV_EXTRAVERSION
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -67,6 +69,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
        [board_ich9lan]         = &e1000_ich9_info,
        [board_ich10lan]        = &e1000_ich10_info,
        [board_pchlan]          = &e1000_pch_info,
+       [board_pch2lan]         = &e1000_pch2_info,
 };
 
 struct e1000_reg_info {
@@ -221,10 +224,10 @@ static void e1000e_dump(struct e1000_adapter *adapter)
        buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
        printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n",
                0, tx_ring->next_to_use, tx_ring->next_to_clean,
-               (u64)buffer_info->dma,
+               (unsigned long long)buffer_info->dma,
                buffer_info->length,
                buffer_info->next_to_watch,
-               (u64)buffer_info->time_stamp);
+               (unsigned long long)buffer_info->time_stamp);
 
        /* Print TX Rings */
        if (!netif_msg_tx_done(adapter))
@@ -276,9 +279,11 @@ static void e1000e_dump(struct e1000_adapter *adapter)
                        "%04X  %3X %016llX %p",
                       (!(le64_to_cpu(u0->b) & (1<<29)) ? 'l' :
                        ((le64_to_cpu(u0->b) & (1<<20)) ? 'd' : 'c')), i,
-                      le64_to_cpu(u0->a), le64_to_cpu(u0->b),
-                      (u64)buffer_info->dma, buffer_info->length,
-                      buffer_info->next_to_watch, (u64)buffer_info->time_stamp,
+                      (unsigned long long)le64_to_cpu(u0->a),
+                      (unsigned long long)le64_to_cpu(u0->b),
+                      (unsigned long long)buffer_info->dma,
+                      buffer_info->length, buffer_info->next_to_watch,
+                      (unsigned long long)buffer_info->time_stamp,
                       buffer_info->skb);
                if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
                        printk(KERN_CONT " NTC/U\n");
@@ -353,19 +358,19 @@ rx_ring_summary:
                                printk(KERN_INFO "RWB[0x%03X]     %016llX "
                                        "%016llX %016llX %016llX "
                                        "---------------- %p", i,
-                                       le64_to_cpu(u1->a),
-                                       le64_to_cpu(u1->b),
-                                       le64_to_cpu(u1->c),
-                                       le64_to_cpu(u1->d),
+                                       (unsigned long long)le64_to_cpu(u1->a),
+                                       (unsigned long long)le64_to_cpu(u1->b),
+                                       (unsigned long long)le64_to_cpu(u1->c),
+                                       (unsigned long long)le64_to_cpu(u1->d),
                                        buffer_info->skb);
                        } else {
                                printk(KERN_INFO "R  [0x%03X]     %016llX "
                                        "%016llX %016llX %016llX %016llX %p", i,
-                                       le64_to_cpu(u1->a),
-                                       le64_to_cpu(u1->b),
-                                       le64_to_cpu(u1->c),
-                                       le64_to_cpu(u1->d),
-                                       (u64)buffer_info->dma,
+                                       (unsigned long long)le64_to_cpu(u1->a),
+                                       (unsigned long long)le64_to_cpu(u1->b),
+                                       (unsigned long long)le64_to_cpu(u1->c),
+                                       (unsigned long long)le64_to_cpu(u1->d),
+                                       (unsigned long long)buffer_info->dma,
                                        buffer_info->skb);
 
                                if (netif_msg_pktdata(adapter))
@@ -402,9 +407,11 @@ rx_ring_summary:
                        buffer_info = &rx_ring->buffer_info[i];
                        u0 = (struct my_u0 *)rx_desc;
                        printk(KERN_INFO "Rl[0x%03X]    %016llX %016llX "
-                               "%016llX %p",
-                               i, le64_to_cpu(u0->a), le64_to_cpu(u0->b),
-                               (u64)buffer_info->dma, buffer_info->skb);
+                               "%016llX %p", i,
+                               (unsigned long long)le64_to_cpu(u0->a),
+                               (unsigned long long)le64_to_cpu(u0->b),
+                               (unsigned long long)buffer_info->dma,
+                               buffer_info->skb);
                        if (i == rx_ring->next_to_use)
                                printk(KERN_CONT " NTU\n");
                        else if (i == rx_ring->next_to_clean)
@@ -1778,25 +1785,25 @@ void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter)
 void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
 {
        int err;
-       int numvecs, i;
-
+       int i;
 
        switch (adapter->int_mode) {
        case E1000E_INT_MODE_MSIX:
                if (adapter->flags & FLAG_HAS_MSIX) {
-                       numvecs = 3; /* RxQ0, TxQ0 and other */
-                       adapter->msix_entries = kcalloc(numvecs,
+                       adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */
+                       adapter->msix_entries = kcalloc(adapter->num_vectors,
                                                      sizeof(struct msix_entry),
                                                      GFP_KERNEL);
                        if (adapter->msix_entries) {
-                               for (i = 0; i < numvecs; i++)
+                               for (i = 0; i < adapter->num_vectors; i++)
                                        adapter->msix_entries[i].entry = i;
 
                                err = pci_enable_msix(adapter->pdev,
                                                      adapter->msix_entries,
-                                                     numvecs);
-                               if (err == 0)
+                                                     adapter->num_vectors);
+                               if (err == 0) {
                                        return;
+                               }
                        }
                        /* MSI-X failed, so fall through and try MSI */
                        e_err("Failed to initialize MSI-X interrupts.  "
@@ -1818,6 +1825,9 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
                /* Don't do anything; this is the system default */
                break;
        }
+
+       /* store the number of vectors being used */
+       adapter->num_vectors = 1;
 }
 
 /**
@@ -1939,7 +1949,14 @@ static void e1000_irq_disable(struct e1000_adapter *adapter)
        if (adapter->msix_entries)
                ew32(EIAC_82574, 0);
        e1e_flush();
-       synchronize_irq(adapter->pdev->irq);
+
+       if (adapter->msix_entries) {
+               int i;
+               for (i = 0; i < adapter->num_vectors; i++)
+                       synchronize_irq(adapter->msix_entries[i].vector);
+       } else {
+               synchronize_irq(adapter->pdev->irq);
+       }
 }
 
 /**
@@ -2723,6 +2740,16 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
                e1e_wphy(hw, 22, phy_data);
        }
 
+       /* Workaround Si errata on 82579 - configure jumbo frame flow */
+       if (hw->mac.type == e1000_pch2lan) {
+               s32 ret_val;
+
+               if (rctl & E1000_RCTL_LPE)
+                       ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
+               else
+                       ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
+       }
+
        /* Setup buffer sizes */
        rctl &= ~E1000_RCTL_SZ_4096;
        rctl |= E1000_RCTL_BSEX;
@@ -2759,7 +2786,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
         * per packet.
         */
        pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-       if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) &&
+       if (!(adapter->flags & FLAG_HAS_ERT) && (pages <= 3) &&
            (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
                adapter->rx_ps_pages = pages;
        else
@@ -2901,10 +2928,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
                         * dropped transactions.
                         */
                        pm_qos_update_request(
-                               adapter->netdev->pm_qos_req, 55);
+                               &adapter->netdev->pm_qos_req, 55);
                } else {
                        pm_qos_update_request(
-                               adapter->netdev->pm_qos_req,
+                               &adapter->netdev->pm_qos_req,
                                PM_QOS_DEFAULT_VALUE);
                }
        }
@@ -3118,7 +3145,27 @@ void e1000e_reset(struct e1000_adapter *adapter)
         *   with ERT support assuming ERT set to E1000_ERT_2048), or
         * - the full Rx FIFO size minus one full frame
         */
-       if (hw->mac.type == e1000_pchlan) {
+       if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
+               fc->pause_time = 0xFFFF;
+       else
+               fc->pause_time = E1000_FC_PAUSE_TIME;
+       fc->send_xon = 1;
+       fc->current_mode = fc->requested_mode;
+
+       switch (hw->mac.type) {
+       default:
+               if ((adapter->flags & FLAG_HAS_ERT) &&
+                   (adapter->netdev->mtu > ETH_DATA_LEN))
+                       hwm = min(((pba << 10) * 9 / 10),
+                                 ((pba << 10) - (E1000_ERT_2048 << 3)));
+               else
+                       hwm = min(((pba << 10) * 9 / 10),
+                                 ((pba << 10) - adapter->max_frame_size));
+
+               fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
+               fc->low_water = fc->high_water - 8;
+               break;
+       case e1000_pchlan:
                /*
                 * Workaround PCH LOM adapter hangs with certain network
                 * loads.  If hangs persist, try disabling Tx flow control.
@@ -3131,26 +3178,15 @@ void e1000e_reset(struct e1000_adapter *adapter)
                        fc->low_water  = 0x3000;
                }
                fc->refresh_time = 0x1000;
-       } else {
-               if ((adapter->flags & FLAG_HAS_ERT) &&
-                   (adapter->netdev->mtu > ETH_DATA_LEN))
-                       hwm = min(((pba << 10) * 9 / 10),
-                                 ((pba << 10) - (E1000_ERT_2048 << 3)));
-               else
-                       hwm = min(((pba << 10) * 9 / 10),
-                                 ((pba << 10) - adapter->max_frame_size));
-
-               fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
-               fc->low_water = fc->high_water - 8;
+               break;
+       case e1000_pch2lan:
+               fc->high_water = 0x05C20;
+               fc->low_water = 0x05048;
+               fc->pause_time = 0x0650;
+               fc->refresh_time = 0x0400;
+               break;
        }
 
-       if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
-               fc->pause_time = 0xFFFF;
-       else
-               fc->pause_time = E1000_FC_PAUSE_TIME;
-       fc->send_xon = 1;
-       fc->current_mode = fc->requested_mode;
-
        /* Allow time for pending master requests to run */
        mac->ops.reset_hw(hw);
 
@@ -3162,8 +3198,6 @@ void e1000e_reset(struct e1000_adapter *adapter)
                e1000_get_hw_control(adapter);
 
        ew32(WUC, 0);
-       if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)
-               e1e_wphy(&adapter->hw, BM_WUC, 0);
 
        if (mac->ops.init_hw(hw))
                e_err("Hardware Error\n");
@@ -3194,12 +3228,6 @@ int e1000e_up(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
 
-       /* DMA latency requirement to workaround early-receive/jumbo issue */
-       if (adapter->flags & FLAG_HAS_ERT)
-               adapter->netdev->pm_qos_req =
-                       pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
-                                      PM_QOS_DEFAULT_VALUE);
-
        /* hardware has been reset, we need to reload some things */
        e1000_configure(adapter);
 
@@ -3263,12 +3291,6 @@ void e1000e_down(struct e1000_adapter *adapter)
        e1000_clean_tx_ring(adapter);
        e1000_clean_rx_ring(adapter);
 
-       if (adapter->flags & FLAG_HAS_ERT) {
-               pm_qos_remove_request(
-                             adapter->netdev->pm_qos_req);
-               adapter->netdev->pm_qos_req = NULL;
-       }
-
        /*
         * TODO: for power management, we could drop the link and
         * pci_disable_device here.
@@ -3419,13 +3441,18 @@ static int e1000_test_msi(struct e1000_adapter *adapter)
 
        /* disable SERR in case the MSI write causes a master abort */
        pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
-       pci_write_config_word(adapter->pdev, PCI_COMMAND,
-                             pci_cmd & ~PCI_COMMAND_SERR);
+       if (pci_cmd & PCI_COMMAND_SERR)
+               pci_write_config_word(adapter->pdev, PCI_COMMAND,
+                                     pci_cmd & ~PCI_COMMAND_SERR);
 
        err = e1000_test_msi_interrupt(adapter);
 
-       /* restore previous setting of command word */
-       pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
+       /* re-enable SERR */
+       if (pci_cmd & PCI_COMMAND_SERR) {
+               pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
+               pci_cmd |= PCI_COMMAND_SERR;
+               pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
+       }
 
        /* success ! */
        if (!err)
@@ -3498,6 +3525,12 @@ static int e1000_open(struct net_device *netdev)
             E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
                e1000_update_mng_vlan(adapter);
 
+       /* DMA latency requirement to workaround early-receive/jumbo issue */
+       if (adapter->flags & FLAG_HAS_ERT)
+               pm_qos_add_request(&adapter->netdev->pm_qos_req,
+                                  PM_QOS_CPU_DMA_LATENCY,
+                                  PM_QOS_DEFAULT_VALUE);
+
        /*
         * before we allocate an interrupt, we must be ready to handle it.
         * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
@@ -3602,6 +3635,9 @@ static int e1000_close(struct net_device *netdev)
        if (adapter->flags & FLAG_HAS_AMT)
                e1000_release_hw_control(adapter);
 
+       if (adapter->flags & FLAG_HAS_ERT)
+               pm_qos_remove_request(&adapter->netdev->pm_qos_req);
+
        pm_runtime_put_sync(&pdev->dev);
 
        return 0;
@@ -3671,6 +3707,110 @@ static void e1000_update_phy_info(unsigned long data)
        schedule_work(&adapter->update_phy_task);
 }
 
+/**
+ * e1000e_update_phy_stats - Update the PHY statistics counters
+ * @adapter: board private structure
+ **/
+static void e1000e_update_phy_stats(struct e1000_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       s32 ret_val;
+       u16 phy_data;
+
+       ret_val = hw->phy.ops.acquire(hw);
+       if (ret_val)
+               return;
+
+       hw->phy.addr = 1;
+
+#define HV_PHY_STATS_PAGE      778
+       /*
+        * A page set is expensive so check if already on desired page.
+        * If not, set to the page with the PHY status registers.
+        */
+       ret_val = e1000e_read_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                          &phy_data);
+       if (ret_val)
+               goto release;
+       if (phy_data != (HV_PHY_STATS_PAGE << IGP_PAGE_SHIFT)) {
+               ret_val = e1000e_write_phy_reg_mdic(hw,
+                                                   IGP01E1000_PHY_PAGE_SELECT,
+                                                   (HV_PHY_STATS_PAGE <<
+                                                    IGP_PAGE_SHIFT));
+               if (ret_val)
+                       goto release;
+       }
+
+       /* Read/clear the upper 16-bit registers and read/accumulate lower */
+
+       /* Single Collision Count */
+       e1000e_read_phy_reg_mdic(hw, HV_SCC_UPPER & MAX_PHY_REG_ADDRESS,
+                                &phy_data);
+       ret_val = e1000e_read_phy_reg_mdic(hw,
+                                          HV_SCC_LOWER & MAX_PHY_REG_ADDRESS,
+                                          &phy_data);
+       if (!ret_val)
+               adapter->stats.scc += phy_data;
+
+       /* Excessive Collision Count */
+       e1000e_read_phy_reg_mdic(hw, HV_ECOL_UPPER & MAX_PHY_REG_ADDRESS,
+                                &phy_data);
+       ret_val = e1000e_read_phy_reg_mdic(hw,
+                                          HV_ECOL_LOWER & MAX_PHY_REG_ADDRESS,
+                                          &phy_data);
+       if (!ret_val)
+               adapter->stats.ecol += phy_data;
+
+       /* Multiple Collision Count */
+       e1000e_read_phy_reg_mdic(hw, HV_MCC_UPPER & MAX_PHY_REG_ADDRESS,
+                                &phy_data);
+       ret_val = e1000e_read_phy_reg_mdic(hw,
+                                          HV_MCC_LOWER & MAX_PHY_REG_ADDRESS,
+                                          &phy_data);
+       if (!ret_val)
+               adapter->stats.mcc += phy_data;
+
+       /* Late Collision Count */
+       e1000e_read_phy_reg_mdic(hw, HV_LATECOL_UPPER & MAX_PHY_REG_ADDRESS,
+                                &phy_data);
+       ret_val = e1000e_read_phy_reg_mdic(hw,
+                                          HV_LATECOL_LOWER &
+                                          MAX_PHY_REG_ADDRESS,
+                                          &phy_data);
+       if (!ret_val)
+               adapter->stats.latecol += phy_data;
+
+       /* Collision Count - also used for adaptive IFS */
+       e1000e_read_phy_reg_mdic(hw, HV_COLC_UPPER & MAX_PHY_REG_ADDRESS,
+                                &phy_data);
+       ret_val = e1000e_read_phy_reg_mdic(hw,
+                                          HV_COLC_LOWER & MAX_PHY_REG_ADDRESS,
+                                          &phy_data);
+       if (!ret_val)
+               hw->mac.collision_delta = phy_data;
+
+       /* Defer Count */
+       e1000e_read_phy_reg_mdic(hw, HV_DC_UPPER & MAX_PHY_REG_ADDRESS,
+                                &phy_data);
+       ret_val = e1000e_read_phy_reg_mdic(hw,
+                                          HV_DC_LOWER & MAX_PHY_REG_ADDRESS,
+                                          &phy_data);
+       if (!ret_val)
+               adapter->stats.dc += phy_data;
+
+       /* Transmit with no CRS */
+       e1000e_read_phy_reg_mdic(hw, HV_TNCRS_UPPER & MAX_PHY_REG_ADDRESS,
+                                &phy_data);
+       ret_val = e1000e_read_phy_reg_mdic(hw,
+                                          HV_TNCRS_LOWER & MAX_PHY_REG_ADDRESS,
+                                          &phy_data);
+       if (!ret_val)
+               adapter->stats.tncrs += phy_data;
+
+release:
+       hw->phy.ops.release(hw);
+}
+
 /**
  * e1000e_update_stats - Update the board statistics counters
  * @adapter: board private structure
@@ -3680,7 +3820,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
        struct net_device *netdev = adapter->netdev;
        struct e1000_hw *hw = &adapter->hw;
        struct pci_dev *pdev = adapter->pdev;
-       u16 phy_data;
 
        /*
         * Prevent stats update while adapter is being reset, or if the pci
@@ -3700,34 +3839,27 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
        adapter->stats.roc += er32(ROC);
 
        adapter->stats.mpc += er32(MPC);
-       if ((hw->phy.type == e1000_phy_82578) ||
-           (hw->phy.type == e1000_phy_82577)) {
-               e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
-               if (!e1e_rphy(hw, HV_SCC_LOWER, &phy_data))
-                       adapter->stats.scc += phy_data;
-
-               e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
-               if (!e1e_rphy(hw, HV_ECOL_LOWER, &phy_data))
-                       adapter->stats.ecol += phy_data;
-
-               e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
-               if (!e1e_rphy(hw, HV_MCC_LOWER, &phy_data))
-                       adapter->stats.mcc += phy_data;
-
-               e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
-               if (!e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data))
-                       adapter->stats.latecol += phy_data;
-
-               e1e_rphy(hw, HV_DC_UPPER, &phy_data);
-               if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data))
-                       adapter->stats.dc += phy_data;
-       } else {
-               adapter->stats.scc += er32(SCC);
-               adapter->stats.ecol += er32(ECOL);
-               adapter->stats.mcc += er32(MCC);
-               adapter->stats.latecol += er32(LATECOL);
-               adapter->stats.dc += er32(DC);
+
+       /* Half-duplex statistics */
+       if (adapter->link_duplex == HALF_DUPLEX) {
+               if (adapter->flags2 & FLAG2_HAS_PHY_STATS) {
+                       e1000e_update_phy_stats(adapter);
+               } else {
+                       adapter->stats.scc += er32(SCC);
+                       adapter->stats.ecol += er32(ECOL);
+                       adapter->stats.mcc += er32(MCC);
+                       adapter->stats.latecol += er32(LATECOL);
+                       adapter->stats.dc += er32(DC);
+
+                       hw->mac.collision_delta = er32(COLC);
+
+                       if ((hw->mac.type != e1000_82574) &&
+                           (hw->mac.type != e1000_82583))
+                               adapter->stats.tncrs += er32(TNCRS);
+               }
+               adapter->stats.colc += hw->mac.collision_delta;
        }
+
        adapter->stats.xonrxc += er32(XONRXC);
        adapter->stats.xontxc += er32(XONTXC);
        adapter->stats.xoffrxc += er32(XOFFRXC);
@@ -3745,28 +3877,9 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 
        hw->mac.tx_packet_delta = er32(TPT);
        adapter->stats.tpt += hw->mac.tx_packet_delta;
-       if ((hw->phy.type == e1000_phy_82578) ||
-           (hw->phy.type == e1000_phy_82577)) {
-               e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
-               if (!e1e_rphy(hw, HV_COLC_LOWER, &phy_data))
-                       hw->mac.collision_delta = phy_data;
-       } else {
-               hw->mac.collision_delta = er32(COLC);
-       }
-       adapter->stats.colc += hw->mac.collision_delta;
 
        adapter->stats.algnerrc += er32(ALGNERRC);
        adapter->stats.rxerrc += er32(RXERRC);
-       if ((hw->phy.type == e1000_phy_82578) ||
-           (hw->phy.type == e1000_phy_82577)) {
-               e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
-               if (!e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data))
-                       adapter->stats.tncrs += phy_data;
-       } else {
-               if ((hw->mac.type != e1000_82574) &&
-                   (hw->mac.type != e1000_82583))
-                       adapter->stats.tncrs += er32(TNCRS);
-       }
        adapter->stats.cexterr += er32(CEXTERR);
        adapter->stats.tsctc += er32(TSCTC);
        adapter->stats.tsctfc += er32(TSCTFC);
@@ -3865,7 +3978,7 @@ static void e1000_print_link_info(struct e1000_adapter *adapter)
               ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
 }
 
-bool e1000e_has_link(struct e1000_adapter *adapter)
+static bool e1000e_has_link(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        bool link_active = 0;
@@ -4841,14 +4954,7 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
        int retval = 0;
 
        /* copy MAC RARs to PHY RARs */
-       for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
-               mac_reg = er32(RAL(i));
-               e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
-               e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
-               mac_reg = er32(RAH(i));
-               e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
-               e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0xFFFF));
-       }
+       e1000_copy_rx_addrs_to_phy_ich8lan(hw);
 
        /* copy MAC MTA to PHY MTA */
        for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
@@ -5551,8 +5657,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        if (err)
                goto err_sw_init;
 
-       err = -EIO;
-
        memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
        memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
        memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
@@ -5721,11 +5825,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 
        e1000_print_device_info(adapter);
 
-       if (pci_dev_run_wake(pdev)) {
-               pm_runtime_set_active(&pdev->dev);
-               pm_runtime_enable(&pdev->dev);
-       }
-       pm_schedule_suspend(&pdev->dev, MSEC_PER_SEC);
+       if (pci_dev_run_wake(pdev))
+               pm_runtime_put_noidle(&pdev->dev);
 
        return 0;
 
@@ -5771,8 +5872,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
        struct e1000_adapter *adapter = netdev_priv(netdev);
        bool down = test_bit(__E1000_DOWN, &adapter->state);
 
-       pm_runtime_get_sync(&pdev->dev);
-
        /*
         * flush_scheduled work may reschedule our watchdog task, so
         * explicitly disable watchdog tasks from being rescheduled
@@ -5797,11 +5896,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
                clear_bit(__E1000_DOWN, &adapter->state);
        unregister_netdev(netdev);
 
-       if (pci_dev_run_wake(pdev)) {
-               pm_runtime_disable(&pdev->dev);
-               pm_runtime_set_suspended(&pdev->dev);
-       }
-       pm_runtime_put_noidle(&pdev->dev);
+       if (pci_dev_run_wake(pdev))
+               pm_runtime_get_noresume(&pdev->dev);
 
        /*
         * Release control of h/w to f/w.  If f/w is AMT enabled, this
@@ -5899,6 +5995,9 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
 
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan },
+
        { }     /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
@@ -5935,7 +6034,7 @@ static int __init e1000_init_module(void)
        int ret;
        pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
                e1000e_driver_version);
-       pr_info("Copyright (c) 1999 - 2009 Intel Corporation.\n");
+       pr_info("Copyright (c) 1999 - 2010 Intel Corporation.\n");
        ret = pci_register_driver(&e1000_driver);
 
        return ret;