From 040babf9d84e7010c457e9ce69e9eb1c27927c9e Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Wed, 31 Oct 2007 15:22:05 -0700 Subject: e1000/e1000e: Move PCI-Express device IDs over to e1000e e1000e will from now on support the PCI-Express adapters that previously were supported by e1000. This support means better performance and easier debugging from now on for both the old PCI-X/PCI hardware and PCI-Express adapters. This patch also moves 3 recently merged device IDs over to e1000e that are identical to quad-port versions of already existing dual port versions. With this last bit every former e1000 pci-e device should work now with e1000e. Here is a brief list of which gigabit driver to use with which adapter: e1000: 82540 -> 82547 e1000e: 82571 -> 82573 ich8, ich9 (82562 or 82566) es2lan (80003eslan) igb: (not yet merged, only available from e1000.sf.net) 82575 Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'drivers/net/e1000/e1000_main.c') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 76c0fa690cc6..f318634c997d 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -73,14 +73,6 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x1026), INTEL_E1000_ETHERNET_DEVICE(0x1027), INTEL_E1000_ETHERNET_DEVICE(0x1028), - INTEL_E1000_ETHERNET_DEVICE(0x1049), - INTEL_E1000_ETHERNET_DEVICE(0x104A), - INTEL_E1000_ETHERNET_DEVICE(0x104B), - INTEL_E1000_ETHERNET_DEVICE(0x104C), - INTEL_E1000_ETHERNET_DEVICE(0x104D), - INTEL_E1000_ETHERNET_DEVICE(0x105E), - INTEL_E1000_ETHERNET_DEVICE(0x105F), - INTEL_E1000_ETHERNET_DEVICE(0x1060), INTEL_E1000_ETHERNET_DEVICE(0x1075), INTEL_E1000_ETHERNET_DEVICE(0x1076), INTEL_E1000_ETHERNET_DEVICE(0x1077), @@ -89,28 +81,9 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x107A), INTEL_E1000_ETHERNET_DEVICE(0x107B), INTEL_E1000_ETHERNET_DEVICE(0x107C), - INTEL_E1000_ETHERNET_DEVICE(0x107D), - INTEL_E1000_ETHERNET_DEVICE(0x107E), - INTEL_E1000_ETHERNET_DEVICE(0x107F), INTEL_E1000_ETHERNET_DEVICE(0x108A), - INTEL_E1000_ETHERNET_DEVICE(0x108B), - INTEL_E1000_ETHERNET_DEVICE(0x108C), - INTEL_E1000_ETHERNET_DEVICE(0x1096), - INTEL_E1000_ETHERNET_DEVICE(0x1098), INTEL_E1000_ETHERNET_DEVICE(0x1099), - INTEL_E1000_ETHERNET_DEVICE(0x109A), - INTEL_E1000_ETHERNET_DEVICE(0x10A4), - INTEL_E1000_ETHERNET_DEVICE(0x10A5), INTEL_E1000_ETHERNET_DEVICE(0x10B5), - INTEL_E1000_ETHERNET_DEVICE(0x10B9), - INTEL_E1000_ETHERNET_DEVICE(0x10BA), - INTEL_E1000_ETHERNET_DEVICE(0x10BB), - INTEL_E1000_ETHERNET_DEVICE(0x10BC), - INTEL_E1000_ETHERNET_DEVICE(0x10C4), - INTEL_E1000_ETHERNET_DEVICE(0x10C5), - INTEL_E1000_ETHERNET_DEVICE(0x10D5), - INTEL_E1000_ETHERNET_DEVICE(0x10D9), - INTEL_E1000_ETHERNET_DEVICE(0x10DA), /* required last entry */ {0,} }; -- cgit v1.2.3 From ef90e4eca9fcade05dd03f853df75cf459a75422 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 13 Nov 2007 20:49:15 -0800 Subject: [E1000]: update netstats traffic counters realtime formerly e1000/e1000e only updated traffic counters once every 2 seconds with the register values of bytes/packets. With newer code however in the interrupt and polling code we can real-time fill in these values in the netstats struct for users to see. Signed-off-by: Auke Kok Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net/e1000/e1000_main.c') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index f318634c997d..40dbe4cfe556 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3653,10 +3653,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 +4028,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; } @@ -4254,6 +4252,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 +4441,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; } -- cgit v1.2.3 From db0ce50d3792e993a1b24f16fb70153eccf38f33 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 13 Nov 2007 20:54:59 -0800 Subject: [E1000]: Secondary unicast address support Add support for configuring secondary unicast addresses. Unicast addresses take precendece over multicast addresses when filling the exact address filters to avoid going to promiscous mode. When more unicast addresses are present than filter slots, unicast filtering is disabled and all slots can be used for multicast addresses. Signed-off-by: Patrick McHardy Signed-off-by: Auke Kok Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 47 ++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'drivers/net/e1000/e1000_main.c') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 40dbe4cfe556..ade483e6e6d0 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -126,7 +126,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); @@ -487,7 +487,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); @@ -900,7 +900,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; @@ -2383,21 +2383,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 +2421,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 +2440,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 +2451,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 +2464,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 +2476,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); } @@ -5070,7 +5085,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) { -- cgit v1.2.3 From 3e18826c73735eee5fca92584137824d9a387008 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Dec 2007 19:49:39 +0000 Subject: e1000 endianness annotations Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net/e1000/e1000_main.c') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ade483e6e6d0..d3665bc9bd40 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -272,14 +272,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; } } @@ -4092,8 +4092,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++; @@ -4621,7 +4621,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, -- cgit v1.2.3 From 67cefcbafc16d01f9d64be8c62cccfd30b3b07c2 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 13 Dec 2007 09:36:53 -0800 Subject: e1000: remove no longer used code for pci read/write cfg Signed-off-by: Adrian Bunk Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'drivers/net/e1000/e1000_main.c') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index d3665bc9bd40..5b129964e832 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -4864,22 +4864,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) { -- cgit v1.2.3 From 67b3c27c8a8d8f81ffc3fe0afc0d805d66744d18 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 17 Dec 2007 13:50:23 -0800 Subject: e1000: Dump the eeprom when a user encounters a bad checksum To help supporting users with a bad eeprom checksum, dump the eeprom info when such a situation is encountered by a user. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 85 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 11 deletions(-) (limited to 'drivers/net/e1000/e1000_main.c') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5b129964e832..7f5b2ae70d5d 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -817,6 +817,64 @@ e1000_reset(struct e1000_adapter *adapter) e1000_release_manageability(adapter); } +/** + * Dump the eeprom for users having checksum issues + **/ +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 @@ -968,7 +1026,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 +1037,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); -- cgit v1.2.3