e1000e: don't clean Rx ring while resetting
[safe/jmp/linux-2.6] / drivers / net / e1000e / netdev.c
index d092eaf..e819f19 100644 (file)
@@ -48,7 +48,7 @@
 
 #include "e1000.h"
 
-#define DRV_VERSION "0.3.3.4-k2"
+#define DRV_VERSION "1.0.2-k2"
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -62,6 +62,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
        [board_ich8lan]         = &e1000_ich8_info,
        [board_ich9lan]         = &e1000_ich9_info,
        [board_ich10lan]        = &e1000_ich10_info,
+       [board_pchlan]          = &e1000_pch_info,
 };
 
 #ifdef DEBUG
@@ -166,7 +167,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
        struct e1000_buffer *buffer_info;
        struct sk_buff *skb;
        unsigned int i;
-       unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
+       unsigned int bufsz = adapter->rx_buffer_len;
 
        i = rx_ring->next_to_use;
        buffer_info = &rx_ring->buffer_info[i];
@@ -178,20 +179,13 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
                        goto map_skb;
                }
 
-               skb = netdev_alloc_skb(netdev, bufsz);
+               skb = netdev_alloc_skb_ip_align(netdev, bufsz);
                if (!skb) {
                        /* Better luck next round */
                        adapter->alloc_rx_buff_failed++;
                        break;
                }
 
-               /*
-                * Make buffer alignment 2 beyond a 16 byte boundary
-                * this will result in a 16 byte aligned IP header after
-                * the 14 byte MAC header is removed
-                */
-               skb_reserve(skb, NET_IP_ALIGN);
-
                buffer_info->skb = skb;
 map_skb:
                buffer_info->dma = pci_map_single(pdev, skb->data,
@@ -283,21 +277,14 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                             cpu_to_le64(ps_page->dma);
                }
 
-               skb = netdev_alloc_skb(netdev,
-                                      adapter->rx_ps_bsize0 + NET_IP_ALIGN);
+               skb = netdev_alloc_skb_ip_align(netdev,
+                                               adapter->rx_ps_bsize0);
 
                if (!skb) {
                        adapter->alloc_rx_buff_failed++;
                        break;
                }
 
-               /*
-                * Make buffer alignment 2 beyond a 16 byte boundary
-                * this will result in a 16 byte aligned IP header after
-                * the 14 byte MAC header is removed
-                */
-               skb_reserve(skb, NET_IP_ALIGN);
-
                buffer_info->skb = skb;
                buffer_info->dma = pci_map_single(pdev, skb->data,
                                                  adapter->rx_ps_bsize0,
@@ -358,9 +345,7 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
        struct e1000_buffer *buffer_info;
        struct sk_buff *skb;
        unsigned int i;
-       unsigned int bufsz = 256 -
-                            16 /* for skb_reserve */ -
-                            NET_IP_ALIGN;
+       unsigned int bufsz = 256 - 16 /* for skb_reserve */;
 
        i = rx_ring->next_to_use;
        buffer_info = &rx_ring->buffer_info[i];
@@ -372,19 +357,13 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
                        goto check_page;
                }
 
-               skb = netdev_alloc_skb(netdev, bufsz);
+               skb = netdev_alloc_skb_ip_align(netdev, bufsz);
                if (unlikely(!skb)) {
                        /* Better luck next round */
                        adapter->alloc_rx_buff_failed++;
                        break;
                }
 
-               /* Make buffer alignment 2 beyond a 16 byte boundary
-                * this will result in a 16 byte aligned IP header after
-                * the 14 byte MAC header is removed
-                */
-               skb_reserve(skb, NET_IP_ALIGN);
-
                buffer_info->skb = skb;
 check_page:
                /* allocate a new page if necessary */
@@ -512,9 +491,8 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                 */
                if (length < copybreak) {
                        struct sk_buff *new_skb =
-                           netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
+                           netdev_alloc_skb_ip_align(netdev, length);
                        if (new_skb) {
-                               skb_reserve(new_skb, NET_IP_ALIGN);
                                skb_copy_to_linear_data_offset(new_skb,
                                                               -NET_IP_ALIGN,
                                                               (skb->data -
@@ -559,8 +537,8 @@ next_desc:
 
        adapter->total_rx_bytes += total_rx_bytes;
        adapter->total_rx_packets += total_rx_packets;
-       adapter->net_stats.rx_bytes += total_rx_bytes;
-       adapter->net_stats.rx_packets += total_rx_packets;
+       netdev->stats.rx_bytes += total_rx_bytes;
+       netdev->stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -621,15 +599,16 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
        struct e1000_buffer *buffer_info;
        unsigned int i, eop;
        unsigned int count = 0;
-       bool cleaned = 0;
        unsigned int total_tx_bytes = 0, total_tx_packets = 0;
 
        i = tx_ring->next_to_clean;
        eop = tx_ring->buffer_info[i].next_to_watch;
        eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
-       while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-               for (cleaned = 0; !cleaned; ) {
+       while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+              (count < tx_ring->count)) {
+               bool cleaned = false;
+               for (; !cleaned; count++) {
                        tx_desc = E1000_TX_DESC(*tx_ring, i);
                        buffer_info = &tx_ring->buffer_info[i];
                        cleaned = (i == eop);
@@ -655,17 +634,13 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 
                eop = tx_ring->buffer_info[i].next_to_watch;
                eop_desc = E1000_TX_DESC(*tx_ring, eop);
-#define E1000_TX_WEIGHT 64
-               /* weight of a sort for tx, to avoid endless transmit cleanup */
-               if (count++ == E1000_TX_WEIGHT)
-                       break;
        }
 
        tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD 32
-       if (cleaned && netif_carrier_ok(netdev) &&
-                    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
+       if (count && netif_carrier_ok(netdev) &&
+           e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
                /* Make sure that anybody stopping the queue after this
                 * sees the new next_to_clean.
                 */
@@ -682,8 +657,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
                /* Detect a transmit hang in hardware, this serializes the
                 * check with the clearing of time_stamp and movement of i */
                adapter->detect_tx_hung = 0;
-               if (tx_ring->buffer_info[eop].time_stamp &&
-                   time_after(jiffies, tx_ring->buffer_info[eop].time_stamp
+               if (tx_ring->buffer_info[i].time_stamp &&
+                   time_after(jiffies, tx_ring->buffer_info[i].time_stamp
                               + (adapter->tx_timeout_factor * HZ))
                    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
                        e1000_print_tx_hang(adapter);
@@ -692,9 +667,9 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
        }
        adapter->total_tx_bytes += total_tx_bytes;
        adapter->total_tx_packets += total_tx_packets;
-       adapter->net_stats.tx_bytes += total_tx_bytes;
-       adapter->net_stats.tx_packets += total_tx_packets;
-       return cleaned;
+       netdev->stats.tx_bytes += total_tx_bytes;
+       netdev->stats.tx_packets += total_tx_packets;
+       return (count < tx_ring->count);
 }
 
 /**
@@ -873,8 +848,8 @@ next_desc:
 
        adapter->total_rx_bytes += total_rx_bytes;
        adapter->total_rx_packets += total_rx_packets;
-       adapter->net_stats.rx_bytes += total_rx_bytes;
-       adapter->net_stats.rx_packets += total_rx_packets;
+       netdev->stats.rx_bytes += total_rx_bytes;
+       netdev->stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -1053,8 +1028,8 @@ next_desc:
 
        adapter->total_rx_bytes += total_rx_bytes;
        adapter->total_rx_packets += total_rx_packets;
-       adapter->net_stats.rx_bytes += total_rx_bytes;
-       adapter->net_stats.rx_packets += total_rx_packets;
+       netdev->stats.rx_bytes += total_rx_bytes;
+       netdev->stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -1201,7 +1176,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
        struct e1000_hw *hw = &adapter->hw;
        u32 rctl, icr = er32(ICR);
 
-       if (!icr)
+       if (!icr || test_bit(__E1000_DOWN, &adapter->state))
                return IRQ_NONE;  /* Not our interrupt */
 
        /*
@@ -1264,7 +1239,8 @@ static irqreturn_t e1000_msix_other(int irq, void *data)
        u32 icr = er32(ICR);
 
        if (!(icr & E1000_ICR_INT_ASSERTED)) {
-               ew32(IMS, E1000_IMS_OTHER);
+               if (!test_bit(__E1000_DOWN, &adapter->state))
+                       ew32(IMS, E1000_IMS_OTHER);
                return IRQ_NONE;
        }
 
@@ -1281,7 +1257,8 @@ static irqreturn_t e1000_msix_other(int irq, void *data)
        }
 
 no_link_interrupt:
-       ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
+       if (!test_bit(__E1000_DOWN, &adapter->state))
+               ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
 
        return IRQ_HANDLED;
 }
@@ -1481,7 +1458,7 @@ static int e1000_request_msix(struct e1000_adapter *adapter)
        else
                memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
        err = request_irq(adapter->msix_entries[vector].vector,
-                         &e1000_intr_msix_rx, 0, adapter->rx_ring->name,
+                         e1000_intr_msix_rx, 0, adapter->rx_ring->name,
                          netdev);
        if (err)
                goto out;
@@ -1494,7 +1471,7 @@ static int e1000_request_msix(struct e1000_adapter *adapter)
        else
                memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
        err = request_irq(adapter->msix_entries[vector].vector,
-                         &e1000_intr_msix_tx, 0, adapter->tx_ring->name,
+                         e1000_intr_msix_tx, 0, adapter->tx_ring->name,
                          netdev);
        if (err)
                goto out;
@@ -1503,7 +1480,7 @@ static int e1000_request_msix(struct e1000_adapter *adapter)
        vector++;
 
        err = request_irq(adapter->msix_entries[vector].vector,
-                         &e1000_msix_other, 0, netdev->name, netdev);
+                         e1000_msix_other, 0, netdev->name, netdev);
        if (err)
                goto out;
 
@@ -1534,7 +1511,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter)
                e1000e_set_interrupt_capability(adapter);
        }
        if (adapter->flags & FLAG_MSI_ENABLED) {
-               err = request_irq(adapter->pdev->irq, &e1000_intr_msi, 0,
+               err = request_irq(adapter->pdev->irq, e1000_intr_msi, 0,
                                  netdev->name, netdev);
                if (!err)
                        return err;
@@ -1544,7 +1521,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter)
                adapter->int_mode = E1000E_INT_MODE_LEGACY;
        }
 
-       err = request_irq(adapter->pdev->irq, &e1000_intr, IRQF_SHARED,
+       err = request_irq(adapter->pdev->irq, e1000_intr, IRQF_SHARED,
                          netdev->name, netdev);
        if (err)
                e_err("Unable to allocate interrupt, Error: %d\n", err);
@@ -1997,7 +1974,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
        struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
        struct e1000_hw *hw = &adapter->hw;
        struct net_device *poll_dev = adapter->netdev;
-       int tx_cleaned = 0, work_done = 0;
+       int tx_cleaned = 1, work_done = 0;
 
        adapter = netdev_priv(poll_dev);
 
@@ -2010,7 +1987,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
 clean_rx:
        adapter->clean_rx(adapter, &work_done, budget);
 
-       if (tx_cleaned)
+       if (!tx_cleaned)
                work_done = budget;
 
        /* If budget not fully consumed, exit the polling mode */
@@ -2018,10 +1995,12 @@ clean_rx:
                if (adapter->itr_setting & 3)
                        e1000_set_itr(adapter);
                napi_complete(napi);
-               if (adapter->msix_entries)
-                       ew32(IMS, adapter->rx_ring->ims_val);
-               else
-                       e1000_irq_enable(adapter);
+               if (!test_bit(__E1000_DOWN, &adapter->state)) {
+                       if (adapter->msix_entries)
+                               ew32(IMS, adapter->rx_ring->ims_val);
+                       else
+                               e1000_irq_enable(adapter);
+               }
        }
 
        return work_done;
@@ -2202,7 +2181,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
        /* Setup the HW Tx Head and Tail descriptor pointers */
        tdba = tx_ring->dma;
        tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
-       ew32(TDBAL, (tdba & DMA_32BIT_MASK));
+       ew32(TDBAL, (tdba & DMA_BIT_MASK(32)));
        ew32(TDBAH, (tdba >> 32));
        ew32(TDLEN, tdlen);
        ew32(TDH, 0);
@@ -2254,8 +2233,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
                ew32(TARC(1), tarc);
        }
 
-       e1000e_config_collision_dist(hw);
-
        /* Setup Transmit Descriptor Settings for eop descriptor */
        adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
 
@@ -2268,6 +2245,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
 
        ew32(TCTL, tctl);
 
+       e1000e_config_collision_dist(hw);
+
        adapter->tx_queue_len = adapter->netdev->tx_queue_len;
 }
 
@@ -2307,6 +2286,23 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
        if (adapter->flags2 & FLAG2_CRC_STRIPPING)
                rctl |= E1000_RCTL_SECRC;
 
+       /* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
+       if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
+               u16 phy_data;
+
+               e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
+               phy_data &= 0xfff8;
+               phy_data |= (1 << 2);
+               e1e_wphy(hw, PHY_REG(770, 26), phy_data);
+
+               e1e_rphy(hw, 22, &phy_data);
+               phy_data &= 0x0fff;
+               phy_data |= (1 << 14);
+               e1e_wphy(hw, 0x10, 0x2823);
+               e1e_wphy(hw, 0x11, 0x0003);
+               e1e_wphy(hw, 22, phy_data);
+       }
+
        /* Setup buffer sizes */
        rctl &= ~E1000_RCTL_SZ_4096;
        rctl |= E1000_RCTL_BSEX;
@@ -2445,8 +2441,6 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
                ew32(ITR, 1000000000 / (adapter->itr * 256));
 
        ctrl_ext = er32(CTRL_EXT);
-       /* Reset delay timers after every interrupt */
-       ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
        /* Auto-Mask interrupts upon ICR access */
        ctrl_ext |= E1000_CTRL_EXT_IAME;
        ew32(IAM, 0xffffffff);
@@ -2458,7 +2452,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
         * the Base and Length of the Rx Descriptor Ring
         */
        rdba = rx_ring->dma;
-       ew32(RDBAL, (rdba & DMA_32BIT_MASK));
+       ew32(RDBAL, (rdba & DMA_BIT_MASK(32)));
        ew32(RDBAH, (rdba >> 32));
        ew32(RDLEN, rdlen);
        ew32(RDH, 0);
@@ -2750,23 +2744,25 @@ void e1000e_reset(struct e1000_adapter *adapter)
        /*
         * flow control settings
         *
-        * The high water mark must be low enough to fit one full frame
+        * The high water mark must be low enough to fit two full frame
         * (or the size used for early receive) above it in the Rx FIFO.
         * Set it to the lower of:
         * - 90% of the Rx FIFO size, and
         * - the full Rx FIFO size minus the early receive size (for parts
         *   with ERT support assuming ERT set to E1000_ERT_2048), or
-        * - the full Rx FIFO size minus one full frame
+        * - the full Rx FIFO size minus two full frames
         */
-       if (adapter->flags & FLAG_HAS_ERT)
+       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));
+                         ((pba << 10) - (2 * adapter->max_frame_size)));
 
-       fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
-       fc->low_water = fc->high_water - 8;
+       fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
+       fc->low_water = (fc->high_water - (2 * adapter->max_frame_size));
+       fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */
 
        if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
                fc->pause_time = 0xFFFF;
@@ -2786,6 +2782,8 @@ 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");
@@ -2798,7 +2796,8 @@ void e1000e_reset(struct e1000_adapter *adapter)
        e1000e_reset_adaptive(hw);
        e1000_get_phy_info(hw);
 
-       if (!(adapter->flags & FLAG_SMART_POWER_DOWN)) {
+       if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
+           !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
                u16 phy_data = 0;
                /*
                 * speed up time to link by disabling smart power down, ignore
@@ -2825,6 +2824,8 @@ int e1000e_up(struct e1000_adapter *adapter)
                e1000_configure_msix(adapter);
        e1000_irq_enable(adapter);
 
+       netif_wake_queue(adapter->netdev);
+
        /* fire a link change interrupt to start the watchdog */
        ew32(ICS, E1000_ICS_LSC);
        return 0;
@@ -2847,7 +2848,7 @@ void e1000e_down(struct e1000_adapter *adapter)
        ew32(RCTL, rctl & ~E1000_RCTL_EN);
        /* flush and sleep below */
 
-       netif_tx_stop_all_queues(netdev);
+       netif_stop_queue(netdev);
 
        /* disable transmits in the hardware */
        tctl = er32(TCTL);
@@ -2967,7 +2968,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
        if (err)
                goto msi_test_failed;
 
-       err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0,
+       err = request_irq(adapter->pdev->irq, e1000_intr_msi_test, 0,
                          netdev->name, netdev);
        if (err) {
                pci_disable_msi(adapter->pdev);
@@ -3071,6 +3072,8 @@ static int e1000_open(struct net_device *netdev)
        if (test_bit(__E1000_TESTING, &adapter->state))
                return -EBUSY;
 
+       netif_carrier_off(netdev);
+
        /* allocate transmit descriptors */
        err = e1000e_setup_tx_resources(adapter);
        if (err)
@@ -3127,7 +3130,7 @@ static int e1000_open(struct net_device *netdev)
 
        e1000_irq_enable(adapter);
 
-       netif_tx_start_all_queues(netdev);
+       netif_start_queue(netdev);
 
        /* fire a link status change interrupt to start the watchdog */
        ew32(ICS, E1000_ICS_LSC);
@@ -3259,8 +3262,10 @@ static void e1000_update_phy_info(unsigned long data)
  **/
 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
@@ -3280,11 +3285,34 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
        adapter->stats.roc += er32(ROC);
 
        adapter->stats.mpc += er32(MPC);
-       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);
+       if ((hw->phy.type == e1000_phy_82578) ||
+           (hw->phy.type == e1000_phy_82577)) {
+               e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
+               e1e_rphy(hw, HV_SCC_LOWER, &phy_data);
+               adapter->stats.scc += phy_data;
+
+               e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
+               e1e_rphy(hw, HV_ECOL_LOWER, &phy_data);
+               adapter->stats.ecol += phy_data;
+
+               e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
+               e1e_rphy(hw, HV_MCC_LOWER, &phy_data);
+               adapter->stats.mcc += phy_data;
+
+               e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
+               e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data);
+               adapter->stats.latecol += phy_data;
+
+               e1e_rphy(hw, HV_DC_UPPER, &phy_data);
+               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);
+       }
        adapter->stats.xonrxc += er32(XONRXC);
        adapter->stats.xontxc += er32(XONTXC);
        adapter->stats.xoffrxc += er32(XOFFRXC);
@@ -3302,20 +3330,35 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 
        hw->mac.tx_packet_delta = er32(TPT);
        adapter->stats.tpt += hw->mac.tx_packet_delta;
-       hw->mac.collision_delta = er32(COLC);
+       if ((hw->phy.type == e1000_phy_82578) ||
+           (hw->phy.type == e1000_phy_82577)) {
+               e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
+               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->mac.type != e1000_82574) && (hw->mac.type != e1000_82583))
-               adapter->stats.tncrs += er32(TNCRS);
+       if ((hw->phy.type == e1000_phy_82578) ||
+           (hw->phy.type == e1000_phy_82577)) {
+               e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
+               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);
 
        /* Fill out the OS statistics structure */
-       adapter->net_stats.multicast = adapter->stats.mprc;
-       adapter->net_stats.collisions = adapter->stats.colc;
+       netdev->stats.multicast = adapter->stats.mprc;
+       netdev->stats.collisions = adapter->stats.colc;
 
        /* Rx Errors */
 
@@ -3323,22 +3366,22 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
         * RLEC on some newer hardware can be incorrect so build
         * our own version based on RUC and ROC
         */
-       adapter->net_stats.rx_errors = adapter->stats.rxerrc +
+       netdev->stats.rx_errors = adapter->stats.rxerrc +
                adapter->stats.crcerrs + adapter->stats.algnerrc +
                adapter->stats.ruc + adapter->stats.roc +
                adapter->stats.cexterr;
-       adapter->net_stats.rx_length_errors = adapter->stats.ruc +
+       netdev->stats.rx_length_errors = adapter->stats.ruc +
                                              adapter->stats.roc;
-       adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
-       adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
-       adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
+       netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+       netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
+       netdev->stats.rx_missed_errors = adapter->stats.mpc;
 
        /* Tx Errors */
-       adapter->net_stats.tx_errors = adapter->stats.ecol +
+       netdev->stats.tx_errors = adapter->stats.ecol +
                                       adapter->stats.latecol;
-       adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
-       adapter->net_stats.tx_window_errors = adapter->stats.latecol;
-       adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
+       netdev->stats.tx_aborted_errors = adapter->stats.ecol;
+       netdev->stats.tx_window_errors = adapter->stats.latecol;
+       netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
 
        /* Tx Dropped needs to be maintained elsewhere */
 
@@ -3597,7 +3640,6 @@ static void e1000_watchdog_task(struct work_struct *work)
                                phy->ops.cfg_on_link_up(hw);
 
                        netif_carrier_on(netdev);
-                       netif_tx_wake_all_queues(netdev);
 
                        if (!test_bit(__E1000_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
@@ -3611,7 +3653,6 @@ static void e1000_watchdog_task(struct work_struct *work)
                        printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
                               adapter->netdev->name);
                        netif_carrier_off(netdev);
-                       netif_tx_stop_all_queues(netdev);
                        if (!test_bit(__E1000_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
                                          round_jiffies(jiffies + 2 * HZ));
@@ -3648,6 +3689,8 @@ link_up:
                         */
                        adapter->tx_timeout_count++;
                        schedule_work(&adapter->reset_task);
+                       /* return immediately since reset is imminent */
+                       return;
                }
        }
 
@@ -3774,7 +3817,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
        else
                protocol = skb->protocol;
 
-       switch (skb->protocol) {
+       switch (protocol) {
        case cpu_to_be16(ETH_P_IP):
                if (ip_hdr(skb)->protocol == IPPROTO_TCP)
                        cmd_len |= E1000_TXD_CMD_TCP;
@@ -3849,7 +3892,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                buffer_info->length = size;
                buffer_info->time_stamp = jiffies;
                buffer_info->next_to_watch = i;
-               buffer_info->dma = map[0] + offset;
+               buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
                count++;
 
                len -= size;
@@ -3880,7 +3923,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                        buffer_info->length = size;
                        buffer_info->time_stamp = jiffies;
                        buffer_info->next_to_watch = i;
-                       buffer_info->dma = map[f + 1] + offset;
+                       buffer_info->dma = map[f] + offset;
 
                        len -= size;
                        offset += size;
@@ -4030,7 +4073,8 @@ static int e1000_maybe_stop_tx(struct net_device *netdev, int size)
 }
 
 #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
-static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
+                                   struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_ring *tx_ring = adapter->tx_ring;
@@ -4144,7 +4188,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
        if (count) {
                e1000_tx_queue(adapter, tx_flags, count);
-               netdev->trans_start = jiffies;
                /* Make sure there is space in the ring for the next send. */
                e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
 
@@ -4187,10 +4230,8 @@ static void e1000_reset_task(struct work_struct *work)
  **/
 static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
 {
-       struct e1000_adapter *adapter = netdev_priv(netdev);
-
        /* only return the current stats */
-       return &adapter->net_stats;
+       return &netdev->stats;
 }
 
 /**
@@ -4205,27 +4246,17 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
        struct e1000_adapter *adapter = netdev_priv(netdev);
        int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
-       if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
-           (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-               e_err("Invalid MTU setting\n");
+       /* Jumbo frame support */
+       if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
+           !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
+               e_err("Jumbo Frames not supported.\n");
                return -EINVAL;
        }
 
-       /* Jumbo frame size limits */
-       if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
-               if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
-                       e_err("Jumbo Frames not supported.\n");
-                       return -EINVAL;
-               }
-               if (adapter->hw.phy.type == e1000_phy_ife) {
-                       e_err("Jumbo Frames not supported.\n");
-                       return -EINVAL;
-               }
-       }
-
-#define MAX_STD_JUMBO_FRAME_SIZE 9234
-       if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
-               e_err("MTU > 9216 not supported.\n");
+       /* Supported frame sizes */
+       if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
+           (max_frame > adapter->max_hw_frame_size)) {
+               e_err("Unsupported MTU setting\n");
                return -EINVAL;
        }
 
@@ -4289,8 +4320,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
                data->phy_id = adapter->hw.phy.addr;
                break;
        case SIOCGMIIREG:
-               if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
                switch (data->reg_num & 0x1F) {
                case MII_BMCR:
                        data->val_out = adapter->phy_regs.bmcr;
@@ -4345,7 +4374,82 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
        }
 }
 
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 i, mac_reg;
+       u16 phy_reg;
+       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));
+       }
+
+       /* copy MAC MTA to PHY MTA */
+       for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
+               mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
+               e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF));
+               e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF));
+       }
+
+       /* configure PHY Rx Control register */
+       e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg);
+       mac_reg = er32(RCTL);
+       if (mac_reg & E1000_RCTL_UPE)
+               phy_reg |= BM_RCTL_UPE;
+       if (mac_reg & E1000_RCTL_MPE)
+               phy_reg |= BM_RCTL_MPE;
+       phy_reg &= ~(BM_RCTL_MO_MASK);
+       if (mac_reg & E1000_RCTL_MO_3)
+               phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
+                               << BM_RCTL_MO_SHIFT);
+       if (mac_reg & E1000_RCTL_BAM)
+               phy_reg |= BM_RCTL_BAM;
+       if (mac_reg & E1000_RCTL_PMCF)
+               phy_reg |= BM_RCTL_PMCF;
+       mac_reg = er32(CTRL);
+       if (mac_reg & E1000_CTRL_RFCE)
+               phy_reg |= BM_RCTL_RFCE;
+       e1e_wphy(&adapter->hw, BM_RCTL, phy_reg);
+
+       /* enable PHY wakeup in MAC register */
+       ew32(WUFC, wufc);
+       ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
+
+       /* configure and enable PHY wakeup in PHY registers */
+       e1e_wphy(&adapter->hw, BM_WUFC, wufc);
+       e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
+
+       /* activate PHY wakeup */
+       retval = hw->phy.ops.acquire_phy(hw);
+       if (retval) {
+               e_err("Could not acquire PHY\n");
+               return retval;
+       }
+       e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
+       retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
+       if (retval) {
+               e_err("Could not read PHY page 769\n");
+               goto out;
+       }
+       phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
+       retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
+       if (retval)
+               e_err("Could not set PHY Host Wakeup bit\n");
+out:
+       hw->phy.ops.release_phy(hw);
+
+       return retval;
+}
+
+static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -4387,8 +4491,9 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
                #define E1000_CTRL_ADVD3WUC 0x00100000
                /* phy power management enable */
                #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
-               ctrl |= E1000_CTRL_ADVD3WUC |
-                       E1000_CTRL_EN_PHY_PWR_MGMT;
+               ctrl |= E1000_CTRL_ADVD3WUC;
+               if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
+                       ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
                ew32(CTRL, ctrl);
 
                if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
@@ -4406,22 +4511,27 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
                /* Allow time for pending master requests to run */
                e1000e_disable_pcie_master(&adapter->hw);
 
-               ew32(WUC, E1000_WUC_PME_EN);
-               ew32(WUFC, wufc);
-               pci_enable_wake(pdev, PCI_D3hot, 1);
-               pci_enable_wake(pdev, PCI_D3cold, 1);
+               if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
+                       /* enable wakeup by the PHY */
+                       retval = e1000_init_phy_wakeup(adapter, wufc);
+                       if (retval)
+                               return retval;
+               } else {
+                       /* enable wakeup by the MAC */
+                       ew32(WUFC, wufc);
+                       ew32(WUC, E1000_WUC_PME_EN);
+               }
        } else {
                ew32(WUC, 0);
                ew32(WUFC, 0);
-               pci_enable_wake(pdev, PCI_D3hot, 0);
-               pci_enable_wake(pdev, PCI_D3cold, 0);
        }
 
+       *enable_wake = !!wufc;
+
        /* make sure adapter isn't asleep if manageability is enabled */
-       if (adapter->flags & FLAG_MNG_PT_ENABLED) {
-               pci_enable_wake(pdev, PCI_D3hot, 1);
-               pci_enable_wake(pdev, PCI_D3cold, 1);
-       }
+       if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
+           (hw->mac.ops.check_mng_mode(hw)))
+               *enable_wake = true;
 
        if (adapter->hw.phy.type == e1000_phy_igp_3)
                e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
@@ -4434,6 +4544,26 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
        pci_disable_device(pdev);
 
+       return 0;
+}
+
+static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
+{
+       if (sleep && wake) {
+               pci_prepare_to_sleep(pdev);
+               return;
+       }
+
+       pci_wake_from_d3(pdev, wake);
+       pci_set_power_state(pdev, PCI_D3hot);
+}
+
+static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
+                                    bool wake)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+
        /*
         * The pci-e switch on some quad port adapters will report a
         * correctable error when the MAC transitions from D0 to D3.  To
@@ -4449,14 +4579,12 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
                pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
                                      (devctl & ~PCI_EXP_DEVCTL_CERE));
 
-               pci_set_power_state(pdev, pci_choose_state(pdev, state));
+               e1000_power_off(pdev, sleep, wake);
 
                pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
        } else {
-               pci_set_power_state(pdev, pci_choose_state(pdev, state));
+               e1000_power_off(pdev, sleep, wake);
        }
-
-       return 0;
 }
 
 static void e1000e_disable_l1aspm(struct pci_dev *pdev)
@@ -4485,6 +4613,18 @@ static void e1000e_disable_l1aspm(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       int retval;
+       bool wake;
+
+       retval = __e1000_shutdown(pdev, &wake);
+       if (!retval)
+               e1000_complete_shutdown(pdev, true, wake);
+
+       return retval;
+}
+
 static int e1000_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4503,14 +4643,6 @@ static int e1000_resume(struct pci_dev *pdev)
                return err;
        }
 
-       /* AER (Advanced Error Reporting) hooks */
-       err = pci_enable_pcie_error_reporting(pdev);
-       if (err) {
-               dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
-                                   "0x%x\n", err);
-               /* non-fatal, continue */
-       }
-
        pci_set_master(pdev);
 
        pci_enable_wake(pdev, PCI_D3hot, 0);
@@ -4524,8 +4656,37 @@ static int e1000_resume(struct pci_dev *pdev)
        }
 
        e1000e_power_up_phy(adapter);
+
+       /* report the system wakeup cause from S3/S4 */
+       if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
+               u16 phy_data;
+
+               e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
+               if (phy_data) {
+                       e_info("PHY Wakeup cause - %s\n",
+                               phy_data & E1000_WUS_EX ? "Unicast Packet" :
+                               phy_data & E1000_WUS_MC ? "Multicast Packet" :
+                               phy_data & E1000_WUS_BC ? "Broadcast Packet" :
+                               phy_data & E1000_WUS_MAG ? "Magic Packet" :
+                               phy_data & E1000_WUS_LNKC ? "Link Status "
+                               " Change" : "other");
+               }
+               e1e_wphy(&adapter->hw, BM_WUS, ~0);
+       } else {
+               u32 wus = er32(WUS);
+               if (wus) {
+                       e_info("MAC Wakeup cause - %s\n",
+                               wus & E1000_WUS_EX ? "Unicast Packet" :
+                               wus & E1000_WUS_MC ? "Multicast Packet" :
+                               wus & E1000_WUS_BC ? "Broadcast Packet" :
+                               wus & E1000_WUS_MAG ? "Magic Packet" :
+                               wus & E1000_WUS_LNKC ? "Link Status Change" :
+                               "other");
+               }
+               ew32(WUS, ~0);
+       }
+
        e1000e_reset(adapter);
-       ew32(WUS, ~0);
 
        e1000_init_manageability(adapter);
 
@@ -4548,7 +4709,12 @@ static int e1000_resume(struct pci_dev *pdev)
 
 static void e1000_shutdown(struct pci_dev *pdev)
 {
-       e1000_suspend(pdev, PMSG_SUSPEND);
+       bool wake = false;
+
+       __e1000_shutdown(pdev, &wake);
+
+       if (system_state == SYSTEM_POWER_OFF)
+               e1000_complete_shutdown(pdev, false, wake);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4584,6 +4750,9 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
 
        netif_device_detach(netdev);
 
+       if (state == pci_channel_io_perm_failure)
+               return PCI_ERS_RESULT_DISCONNECT;
+
        if (netif_running(netdev))
                e1000e_down(adapter);
        pci_disable_device(pdev);
@@ -4762,16 +4931,16 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
                return err;
 
        pci_using_dac = 0;
-       err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
        if (!err) {
-               err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
                if (!err)
                        pci_using_dac = 1;
        } else {
-               err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (err) {
                        err = pci_set_consistent_dma_mask(pdev,
-                                                         DMA_32BIT_MASK);
+                                                         DMA_BIT_MASK(32));
                        if (err) {
                                dev_err(&pdev->dev, "No usable DMA "
                                        "configuration, aborting\n");
@@ -4786,6 +4955,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        if (err)
                goto err_pci_reg;
 
+       /* AER (Advanced Error Reporting) hooks */
+       pci_enable_pcie_error_reporting(pdev);
+
        pci_set_master(pdev);
        /* PCI config space info */
        err = pci_save_state(pdev);
@@ -4810,6 +4982,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        adapter->flags2 = ei->flags2;
        adapter->hw.adapter = adapter;
        adapter->hw.mac.type = ei->mac;
+       adapter->max_hw_frame_size = ei->max_hw_frame_size;
        adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
 
        mmio_start = pci_resource_start(pdev, 0);
@@ -4965,6 +5138,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
                /* APME bit in EEPROM is mapped to WUC.APME */
                eeprom_data = er32(WUC);
                eeprom_apme_mask = E1000_WUC_APME;
+               if (eeprom_data & E1000_WUC_PHY_WAKE)
+                       adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
        } else if (adapter->flags & FLAG_APME_IN_CTRL3) {
                if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
                    (adapter->hw.bus.func == 1))
@@ -5005,15 +5180,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        if (!(adapter->flags & FLAG_HAS_AMT))
                e1000_get_hw_control(adapter);
 
-       /* tell the stack to leave us alone until e1000_open() is called */
-       netif_carrier_off(netdev);
-       netif_tx_stop_all_queues(netdev);
-
        strcpy(netdev->name, "eth%d");
        err = register_netdev(netdev);
        if (err)
                goto err_register;
 
+       /* carrier off reporting is important to ethtool even BEFORE open */
+       netif_carrier_off(netdev);
+
        e1000_print_device_info(adapter);
 
        return 0;
@@ -5058,7 +5232,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
-       int err;
 
        /*
         * flush_scheduled work may reschedule our watchdog task, so
@@ -5094,10 +5267,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
        free_netdev(netdev);
 
        /* AER disable */
-       err = pci_disable_pcie_error_reporting(pdev);
-       if (err)
-               dev_err(&pdev->dev,
-                       "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+       pci_disable_pcie_error_reporting(pdev);
 
        pci_disable_device(pdev);
 }
@@ -5130,6 +5300,7 @@ static struct pci_device_id e1000_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
 
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
 
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
@@ -5166,6 +5337,11 @@ static struct pci_device_id e1000_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
 
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
+
        { }     /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);