Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[cascardo/linux.git] / drivers / net / igb / igb_main.c
index 928ce82..6f1ad53 100644 (file)
@@ -718,7 +718,8 @@ void igb_down(struct igb_adapter *adapter)
        adapter->link_speed = 0;
        adapter->link_duplex = 0;
 
-       igb_reset(adapter);
+       if (!pci_channel_offline(adapter->pdev))
+               igb_reset(adapter);
        igb_clean_all_tx_rings(adapter);
        igb_clean_all_rx_rings(adapter);
 }
@@ -871,6 +872,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                goto err_pci_reg;
 
        pci_set_master(pdev);
+       pci_save_state(pdev);
 
        err = -ENOMEM;
        netdev = alloc_etherdev(sizeof(struct igb_adapter));
@@ -966,8 +968,13 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                           NETIF_F_HW_VLAN_FILTER;
 
        netdev->features |= NETIF_F_TSO;
-
        netdev->features |= NETIF_F_TSO6;
+
+       netdev->vlan_features |= NETIF_F_TSO;
+       netdev->vlan_features |= NETIF_F_TSO6;
+       netdev->vlan_features |= NETIF_F_HW_CSUM;
+       netdev->vlan_features |= NETIF_F_SG;
+
        if (pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
@@ -3254,6 +3261,13 @@ quit_polling:
 
        return 1;
 }
+
+static inline u32 get_head(struct igb_ring *tx_ring)
+{
+       void *end = (struct e1000_tx_desc *)tx_ring->desc + tx_ring->count;
+       return le32_to_cpu(*(volatile __le32 *)end);
+}
+
 /**
  * igb_clean_tx_irq - Reclaim resources after transmit completes
  * @adapter: board private structure
@@ -3275,9 +3289,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter,
        unsigned int total_bytes = 0, total_packets = 0;
 
        rmb();
-       head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc
-                                + tx_ring->count);
-       head = le32_to_cpu(head);
+       head = get_head(tx_ring);
        i = tx_ring->next_to_clean;
        while (1) {
                while (i != head) {
@@ -3312,9 +3324,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter,
                }
                oldhead = head;
                rmb();
-               head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc
-                                        + tx_ring->count);
-               head = le32_to_cpu(head);
+               head = get_head(tx_ring);
                if (head == oldhead)
                        goto done_cleaning;
        }  /* while (1) */
@@ -3388,7 +3398,7 @@ done_cleaning:
  * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
  * @skb: pointer to sk_buff to be indicated to stack
  **/
-static void igb_receive_skb(struct igb_adapter *adapter, u8 status, u16 vlan,
+static void igb_receive_skb(struct igb_adapter *adapter, u8 status, __le16 vlan,
                            struct sk_buff *skb)
 {
        if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
@@ -3452,8 +3462,8 @@ static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter,
                 * that case, it fills the header buffer and spills the rest
                 * into the page.
                 */
-               hlen = le16_to_cpu((rx_desc->wb.lower.lo_dword.hdr_info &
-                 E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT);
+               hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
+                 E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
                if (hlen > adapter->rx_ps_hdr_size)
                        hlen = adapter->rx_ps_hdr_size;
 
@@ -4076,6 +4086,7 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
                return PCI_ERS_RESULT_DISCONNECT;
        }
        pci_set_master(pdev);
+       pci_restore_state(pdev);
 
        pci_enable_wake(pdev, PCI_D3hot, 0);
        pci_enable_wake(pdev, PCI_D3cold, 0);