Merge branches 'release', 'asus', 'sony-laptop' and 'thinkpad' into release
[pandora-kernel.git] / drivers / net / e1000 / e1000_main.c
index f318634..7c5b05a 100644 (file)
@@ -47,6 +47,12 @@ static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation
  * Macro expands to...
  *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
  */
+#ifdef CONFIG_E1000E_ENABLED
+  #define PCIE(x) 
+#else
+  #define PCIE(x) x,
+#endif
+
 static struct pci_device_id e1000_pci_tbl[] = {
        INTEL_E1000_ETHERNET_DEVICE(0x1000),
        INTEL_E1000_ETHERNET_DEVICE(0x1001),
@@ -73,6 +79,14 @@ static struct pci_device_id e1000_pci_tbl[] = {
        INTEL_E1000_ETHERNET_DEVICE(0x1026),
        INTEL_E1000_ETHERNET_DEVICE(0x1027),
        INTEL_E1000_ETHERNET_DEVICE(0x1028),
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x1049))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x104A))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x104B))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x104C))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x104D))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x105E))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x105F))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x1060))
        INTEL_E1000_ETHERNET_DEVICE(0x1075),
        INTEL_E1000_ETHERNET_DEVICE(0x1076),
        INTEL_E1000_ETHERNET_DEVICE(0x1077),
@@ -81,9 +95,28 @@ static struct pci_device_id e1000_pci_tbl[] = {
        INTEL_E1000_ETHERNET_DEVICE(0x107A),
        INTEL_E1000_ETHERNET_DEVICE(0x107B),
        INTEL_E1000_ETHERNET_DEVICE(0x107C),
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x107D))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x107E))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x107F))
        INTEL_E1000_ETHERNET_DEVICE(0x108A),
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x108B))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x108C))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x1096))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x1098))
        INTEL_E1000_ETHERNET_DEVICE(0x1099),
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x109A))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10A4))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10A5))
        INTEL_E1000_ETHERNET_DEVICE(0x10B5),
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10B9))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10BA))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10BB))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10BC))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10C4))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10C5))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10D5))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10D9))
+PCIE(  INTEL_E1000_ETHERNET_DEVICE(0x10DA))
        /* required last entry */
        {0,}
 };
@@ -126,7 +159,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
                                 struct e1000_tx_ring *tx_ring);
 static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
                                 struct e1000_rx_ring *rx_ring);
-static void e1000_set_multi(struct net_device *netdev);
+static void e1000_set_rx_mode(struct net_device *netdev);
 static void e1000_update_phy_info(unsigned long data);
 static void e1000_watchdog(unsigned long data);
 static void e1000_82547_tx_fifo_stall(unsigned long data);
@@ -272,14 +305,14 @@ module_exit(e1000_exit_module);
 static int e1000_request_irq(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
-       void (*handler) = &e1000_intr;
+       irq_handler_t handler = e1000_intr;
        int irq_flags = IRQF_SHARED;
        int err;
 
        if (adapter->hw.mac_type >= e1000_82571) {
                adapter->have_msi = !pci_enable_msi(adapter->pdev);
                if (adapter->have_msi) {
-                       handler = &e1000_intr_msi;
+                       handler = e1000_intr_msi;
                        irq_flags = 0;
                }
        }
@@ -487,7 +520,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
        struct net_device *netdev = adapter->netdev;
        int i;
 
-       e1000_set_multi(netdev);
+       e1000_set_rx_mode(netdev);
 
        e1000_restore_vlan(adapter);
        e1000_init_manageability(adapter);
@@ -817,6 +850,64 @@ e1000_reset(struct e1000_adapter *adapter)
        e1000_release_manageability(adapter);
 }
 
+/**
+ *  Dump the eeprom for users having checksum issues
+ **/
+static void e1000_dump_eeprom(struct e1000_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct ethtool_eeprom eeprom;
+       const struct ethtool_ops *ops = netdev->ethtool_ops;
+       u8 *data;
+       int i;
+       u16 csum_old, csum_new = 0;
+
+       eeprom.len = ops->get_eeprom_len(netdev);
+       eeprom.offset = 0;
+
+       data = kmalloc(eeprom.len, GFP_KERNEL);
+       if (!data) {
+               printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
+                      " data\n");
+               return;
+       }
+
+       ops->get_eeprom(netdev, &eeprom, data);
+
+       csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
+                  (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
+       for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
+               csum_new += data[i] + (data[i + 1] << 8);
+       csum_new = EEPROM_SUM - csum_new;
+
+       printk(KERN_ERR "/*********************/\n");
+       printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
+       printk(KERN_ERR "Calculated              : 0x%04x\n", csum_new);
+
+       printk(KERN_ERR "Offset    Values\n");
+       printk(KERN_ERR "========  ======\n");
+       print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
+
+       printk(KERN_ERR "Include this output when contacting your support "
+              "provider.\n");
+       printk(KERN_ERR "This is not a software error! Something bad "
+              "happened to your hardware or\n");
+       printk(KERN_ERR "EEPROM image. Ignoring this "
+              "problem could result in further problems,\n");
+       printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
+       printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
+              "which is invalid\n");
+       printk(KERN_ERR "and requires you to set the proper MAC "
+              "address manually before continuing\n");
+       printk(KERN_ERR "to enable this network device.\n");
+       printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
+              "to your hardware vendor\n");
+       printk(KERN_ERR "or Intel Customer Support: linux-nics@intel.com\n");
+       printk(KERN_ERR "/*********************/\n");
+
+       kfree(data);
+}
+
 /**
  * e1000_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -900,7 +991,7 @@ e1000_probe(struct pci_dev *pdev,
        netdev->stop = &e1000_close;
        netdev->hard_start_xmit = &e1000_xmit_frame;
        netdev->get_stats = &e1000_get_stats;
-       netdev->set_multicast_list = &e1000_set_multi;
+       netdev->set_rx_mode = &e1000_set_rx_mode;
        netdev->set_mac_address = &e1000_set_mac;
        netdev->change_mtu = &e1000_change_mtu;
        netdev->do_ioctl = &e1000_ioctl;
@@ -968,7 +1059,6 @@ e1000_probe(struct pci_dev *pdev,
        adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
 
        /* initialize eeprom parameters */
-
        if (e1000_init_eeprom_params(&adapter->hw)) {
                E1000_ERR("EEPROM initialization failed\n");
                goto err_eeprom;
@@ -980,23 +1070,29 @@ e1000_probe(struct pci_dev *pdev,
        e1000_reset_hw(&adapter->hw);
 
        /* make sure the EEPROM is good */
-
        if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
                DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
-               goto err_eeprom;
+               e1000_dump_eeprom(adapter);
+               /*
+                * set MAC address to all zeroes to invalidate and temporary
+                * disable this device for the user. This blocks regular
+                * traffic while still permitting ethtool ioctls from reaching
+                * the hardware as well as allowing the user to run the
+                * interface after manually setting a hw addr using
+                * `ip set address`
+                */
+               memset(adapter->hw.mac_addr, 0, netdev->addr_len);
+       } else {
+               /* copy the MAC address out of the EEPROM */
+               if (e1000_read_mac_addr(&adapter->hw))
+                       DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
        }
-
-       /* copy the MAC address out of the EEPROM */
-
-       if (e1000_read_mac_addr(&adapter->hw))
-               DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
+       /* don't block initalization here due to bad MAC address */
        memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
        memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
 
-       if (!is_valid_ether_addr(netdev->perm_addr)) {
+       if (!is_valid_ether_addr(netdev->perm_addr))
                DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
-               goto err_eeprom;
-       }
 
        e1000_get_bus_info(&adapter->hw);
 
@@ -2383,21 +2479,22 @@ e1000_set_mac(struct net_device *netdev, void *p)
 }
 
 /**
- * e1000_set_multi - Multicast and Promiscuous mode set
+ * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
  * @netdev: network interface device structure
  *
- * The set_multi entry point is called whenever the multicast address
- * list or the network interface flags are updated.  This routine is
- * responsible for configuring the hardware for proper multicast,
+ * The set_rx_mode entry point is called whenever the unicast or multicast
+ * address lists or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper unicast, multicast,
  * promiscuous mode, and all-multi behavior.
  **/
 
 static void
-e1000_set_multi(struct net_device *netdev)
+e1000_set_rx_mode(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       struct dev_mc_list *mc_ptr;
+       struct dev_addr_list *uc_ptr;
+       struct dev_addr_list *mc_ptr;
        uint32_t rctl;
        uint32_t hash_value;
        int i, rar_entries = E1000_RAR_ENTRIES;
@@ -2420,9 +2517,16 @@ e1000_set_multi(struct net_device *netdev)
                rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
        } else if (netdev->flags & IFF_ALLMULTI) {
                rctl |= E1000_RCTL_MPE;
-               rctl &= ~E1000_RCTL_UPE;
        } else {
-               rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+               rctl &= ~E1000_RCTL_MPE;
+       }
+
+       uc_ptr = NULL;
+       if (netdev->uc_count > rar_entries - 1) {
+               rctl |= E1000_RCTL_UPE;
+       } else if (!(netdev->flags & IFF_PROMISC)) {
+               rctl &= ~E1000_RCTL_UPE;
+               uc_ptr = netdev->uc_list;
        }
 
        E1000_WRITE_REG(hw, RCTL, rctl);
@@ -2432,7 +2536,10 @@ e1000_set_multi(struct net_device *netdev)
        if (hw->mac_type == e1000_82542_rev2_0)
                e1000_enter_82542_rst(adapter);
 
-       /* load the first 14 multicast address into the exact filters 1-14
+       /* load the first 14 addresses into the exact filters 1-14. Unicast
+        * addresses take precedence to avoid disabling unicast filtering
+        * when possible.
+        *
         * RAR 0 is used for the station MAC adddress
         * if there are not 14 addresses, go ahead and clear the filters
         * -- with 82571 controllers only 0-13 entries are filled here
@@ -2440,8 +2547,11 @@ e1000_set_multi(struct net_device *netdev)
        mc_ptr = netdev->mc_list;
 
        for (i = 1; i < rar_entries; i++) {
-               if (mc_ptr) {
-                       e1000_rar_set(hw, mc_ptr->dmi_addr, i);
+               if (uc_ptr) {
+                       e1000_rar_set(hw, uc_ptr->da_addr, i);
+                       uc_ptr = uc_ptr->next;
+               } else if (mc_ptr) {
+                       e1000_rar_set(hw, mc_ptr->da_addr, i);
                        mc_ptr = mc_ptr->next;
                } else {
                        E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
@@ -2450,6 +2560,7 @@ e1000_set_multi(struct net_device *netdev)
                        E1000_WRITE_FLUSH(hw);
                }
        }
+       WARN_ON(uc_ptr != NULL);
 
        /* clear the old settings from the multicast hash table */
 
@@ -2461,7 +2572,7 @@ e1000_set_multi(struct net_device *netdev)
        /* load any remaining addresses into the hash table */
 
        for (; mc_ptr; mc_ptr = mc_ptr->next) {
-               hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
+               hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
                e1000_mta_set(hw, hash_value);
        }
 
@@ -3653,10 +3764,6 @@ e1000_update_stats(struct e1000_adapter *adapter)
        }
 
        /* Fill out the OS statistics structure */
-       adapter->net_stats.rx_packets = adapter->stats.gprc;
-       adapter->net_stats.tx_packets = adapter->stats.gptc;
-       adapter->net_stats.rx_bytes = adapter->stats.gorcl;
-       adapter->net_stats.tx_bytes = adapter->stats.gotcl;
        adapter->net_stats.multicast = adapter->stats.mprc;
        adapter->net_stats.collisions = adapter->stats.colc;
 
@@ -4032,6 +4139,8 @@ 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;
 }
 
@@ -4079,8 +4188,8 @@ e1000_rx_checksum(struct e1000_adapter *adapter,
                /* Hardware complements the payload checksum, so we undo it
                 * and then put the value in host order for further stack use.
                 */
-               csum = ntohl(csum ^ 0xFFFF);
-               skb->csum = csum;
+               __sum16 sum = (__force __sum16)htons(csum);
+               skb->csum = csum_unfold(~sum);
                skb->ip_summed = CHECKSUM_COMPLETE;
        }
        adapter->hw_csum_good++;
@@ -4254,6 +4363,8 @@ next_desc:
 
        adapter->total_rx_packets += total_rx_packets;
        adapter->total_rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -4441,6 +4552,8 @@ next_desc:
 
        adapter->total_rx_packets += total_rx_packets;
        adapter->total_rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -4604,7 +4717,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                                rx_desc->read.buffer_addr[j+1] =
                                     cpu_to_le64(ps_page_dma->ps_page_dma[j]);
                        } else
-                               rx_desc->read.buffer_addr[j+1] = ~0;
+                               rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
                }
 
                skb = netdev_alloc_skb(netdev,
@@ -4847,22 +4960,6 @@ e1000_pci_clear_mwi(struct e1000_hw *hw)
        pci_clear_mwi(adapter->pdev);
 }
 
-void
-e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
-{
-       struct e1000_adapter *adapter = hw->back;
-
-       pci_read_config_word(adapter->pdev, reg, value);
-}
-
-void
-e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
-{
-       struct e1000_adapter *adapter = hw->back;
-
-       pci_write_config_word(adapter->pdev, reg, *value);
-}
-
 int
 e1000_pcix_get_mmrbc(struct e1000_hw *hw)
 {
@@ -5068,7 +5165,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
        if (wufc) {
                e1000_setup_rctl(adapter);
-               e1000_set_multi(netdev);
+               e1000_set_rx_mode(netdev);
 
                /* turn on all-multi mode if wake on multicast is enabled */
                if (wufc & E1000_WUFC_MC) {