[kernel] r16425 - in dists/sid/linux-2.6/debian: . patches/bugfix/all patches/series
Ben Hutchings
benh at alioth.debian.org
Sun Oct 10 17:55:09 UTC 2010
Author: benh
Date: Sun Oct 10 17:55:05 2010
New Revision: 16425
Log:
e1000: fix Tx hangs by disabling 64-bit DMA (Closes: #518182)
Added:
dists/sid/linux-2.6/debian/patches/bugfix/all/e1000-fix-Tx-hangs-by-disabling-64-bit-DMA.patch
Modified:
dists/sid/linux-2.6/debian/changelog
dists/sid/linux-2.6/debian/patches/series/25
Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog Sun Oct 10 15:28:05 2010 (r16424)
+++ dists/sid/linux-2.6/debian/changelog Sun Oct 10 17:55:05 2010 (r16425)
@@ -10,6 +10,7 @@
- hisax: Disable device aliases that conflict with mISDN
* Update Danish debconf template translation (Joe Hansen) (Closes: #599457)
* [x86] KVM: SVM: Fix wrong intercept masks on 32 bit (Closes: #599507)
+ * e1000: fix Tx hangs by disabling 64-bit DMA (Closes: #518182)
[ Stephen R. Marenka ]
* m68k: fix missing io macros.
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/e1000-fix-Tx-hangs-by-disabling-64-bit-DMA.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/e1000-fix-Tx-hangs-by-disabling-64-bit-DMA.patch Sun Oct 10 17:55:05 2010 (r16425)
@@ -0,0 +1,247 @@
+From: Jesse Brandeburg <jesse.brandeburg at intel.com>
+Date: Tue, 7 Sep 2010 21:01:12 +0000
+Subject: [PATCH] e1000: fix Tx hangs by disabling 64-bit DMA
+
+commit e508be174ad36b0cf9b324cd04978c2b13c21502 upstream.
+
+Several users report issues with 32-bit adapters when plugged
+into PCI slots in machines with >= 4GB ram. In particular AMD
+systems with HyperTransport to PCI bridges seem to trigger the
+issue, but it isn't limited to only them.
+
+This issue is not easily reproducible here, yet still continues
+to occur in the field. For e1000 on PCI devices, just disable DMA
+addresses over the 4GB boundary when in PCI (not PCI-X) mode, to
+prevent the issue from continuing to pop up. The performance
+impact for this is negligible.
+
+The code was refactored to move the init of the hw struct to its
+own function. This allows the init to be called very early in
+probe, which then allows using hw-> members for this fix.
+
+A slight refactor to the DMA mask code was done for minor
+correctness based on the instructions in DMA-API-HOWTO.
+
+Signed-off-by: Jesse Brandeburg <jesse.brandeburg at intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher at intel.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+[bwh: Adjust for 2.6.32]
+---
+--- a/drivers/net/e1000/e1000_main.c
++++ b/drivers/net/e1000/e1000_main.c
+@@ -790,6 +790,70 @@ static const struct net_device_ops e1000_netdev_ops = {
+ };
+
+ /**
++ * e1000_init_hw_struct - initialize members of hw struct
++ * @adapter: board private struct
++ * @hw: structure used by e1000_hw.c
++ *
++ * Factors out initialization of the e1000_hw struct to its own function
++ * that can be called very early at init (just after struct allocation).
++ * Fields are initialized based on PCI device information and
++ * OS network device settings (MTU size).
++ * Returns negative error codes if MAC type setup fails.
++ */
++static int e1000_init_hw_struct(struct e1000_adapter *adapter,
++ struct e1000_hw *hw)
++{
++ struct pci_dev *pdev = adapter->pdev;
++
++ /* PCI config space info */
++ hw->vendor_id = pdev->vendor;
++ hw->device_id = pdev->device;
++ hw->subsystem_vendor_id = pdev->subsystem_vendor;
++ hw->subsystem_id = pdev->subsystem_device;
++ hw->revision_id = pdev->revision;
++
++ pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
++
++ hw->max_frame_size = adapter->netdev->mtu +
++ ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
++ hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
++
++ /* identify the MAC */
++ if (e1000_set_mac_type(hw)) {
++ DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
++ return -EIO;
++ }
++
++ switch (hw->mac_type) {
++ default:
++ break;
++ case e1000_82541:
++ case e1000_82547:
++ case e1000_82541_rev_2:
++ case e1000_82547_rev_2:
++ hw->phy_init_script = 1;
++ break;
++ }
++
++ e1000_set_media_type(hw);
++ e1000_get_bus_info(hw);
++
++ hw->wait_autoneg_complete = false;
++ hw->tbi_compatibility_en = true;
++ hw->adaptive_ifs = true;
++
++ /* Copper options */
++
++ if (hw->media_type == e1000_media_type_copper) {
++ hw->mdix = AUTO_ALL_MODES;
++ hw->disable_polarity_correction = false;
++ hw->master_slave = E1000_MASTER_SLAVE;
++ }
++
++ return 0;
++}
++
++/**
+ * e1000_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in e1000_pci_tbl
+@@ -826,22 +890,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
+ if (err)
+ return err;
+
+- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
+- !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
+- pci_using_dac = 1;
+- } else {
+- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+- if (err) {
+- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+- if (err) {
+- E1000_ERR("No usable DMA configuration, "
+- "aborting\n");
+- goto err_dma;
+- }
+- }
+- pci_using_dac = 0;
+- }
+-
+ err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
+ if (err)
+ goto err_pci_reg;
+@@ -882,6 +930,32 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
+ }
+ }
+
++ /* make ready for any if (hw->...) below */
++ err = e1000_init_hw_struct(adapter, hw);
++ if (err)
++ goto err_sw_init;
++
++ /*
++ * there is a workaround being applied below that limits
++ * 64-bit DMA addresses to 64-bit hardware. There are some
++ * 32-bit adapters that Tx hang when given 64-bit DMA addresses
++ */
++ pci_using_dac = 0;
++ if ((hw->bus_type == e1000_bus_type_pcix) &&
++ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
++ /*
++ * according to DMA-API-HOWTO, coherent calls will always
++ * succeed if the set call did
++ */
++ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
++ pci_using_dac = 1;
++ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
++ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
++ } else {
++ E1000_ERR("No usable DMA configuration, aborting\n");
++ goto err_dma;
++ }
++
+ netdev->netdev_ops = &e1000_netdev_ops;
+ e1000_set_ethtool_ops(netdev);
+ netdev->watchdog_timeo = 5 * HZ;
+@@ -956,8 +1030,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
+ if (!is_valid_ether_addr(netdev->perm_addr))
+ DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
+
+- e1000_get_bus_info(hw);
+-
+ init_timer(&adapter->tx_fifo_stall_timer);
+ adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
+ adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
+@@ -1070,6 +1142,7 @@ err_eeprom:
+ iounmap(hw->flash_address);
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
++err_dma:
+ err_sw_init:
+ iounmap(hw->hw_addr);
+ err_ioremap:
+@@ -1077,7 +1150,6 @@ err_ioremap:
+ err_alloc_etherdev:
+ pci_release_selected_regions(pdev, bars);
+ err_pci_reg:
+-err_dma:
+ pci_disable_device(pdev);
+ return err;
+ }
+@@ -1129,62 +1201,12 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
+ * @adapter: board private structure to initialize
+ *
+ * e1000_sw_init initializes the Adapter private data structure.
+- * Fields are initialized based on PCI device information and
+- * OS network device settings (MTU size).
++ * e1000_init_hw_struct MUST be called before this function
+ **/
+
+ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
+ {
+- struct e1000_hw *hw = &adapter->hw;
+- struct net_device *netdev = adapter->netdev;
+- struct pci_dev *pdev = adapter->pdev;
+-
+- /* PCI config space info */
+-
+- hw->vendor_id = pdev->vendor;
+- hw->device_id = pdev->device;
+- hw->subsystem_vendor_id = pdev->subsystem_vendor;
+- hw->subsystem_id = pdev->subsystem_device;
+- hw->revision_id = pdev->revision;
+-
+- pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
+-
+ adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+- hw->max_frame_size = netdev->mtu +
+- ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+- hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
+-
+- /* identify the MAC */
+-
+- if (e1000_set_mac_type(hw)) {
+- DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
+- return -EIO;
+- }
+-
+- switch (hw->mac_type) {
+- default:
+- break;
+- case e1000_82541:
+- case e1000_82547:
+- case e1000_82541_rev_2:
+- case e1000_82547_rev_2:
+- hw->phy_init_script = 1;
+- break;
+- }
+-
+- e1000_set_media_type(hw);
+-
+- hw->wait_autoneg_complete = false;
+- hw->tbi_compatibility_en = true;
+- hw->adaptive_ifs = true;
+-
+- /* Copper options */
+-
+- if (hw->media_type == e1000_media_type_copper) {
+- hw->mdix = AUTO_ALL_MODES;
+- hw->disable_polarity_correction = false;
+- hw->master_slave = E1000_MASTER_SLAVE;
+- }
+
+ adapter->num_tx_queues = 1;
+ adapter->num_rx_queues = 1;
Modified: dists/sid/linux-2.6/debian/patches/series/25
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/25 Sun Oct 10 15:28:05 2010 (r16424)
+++ dists/sid/linux-2.6/debian/patches/series/25 Sun Oct 10 17:55:05 2010 (r16425)
@@ -6,3 +6,4 @@
+ debian/isdn-i4l-mark-as-staging.patch
+ debian/hisax-Disable-device-aliases-that-conflict-with-mISDN.patch
+ bugfix/x86/KVM-SVM-Fix-wrong-intercept-masks-on-32-bit.patch
++ bugfix/all/e1000-fix-Tx-hangs-by-disabling-64-bit-DMA.patch
More information about the Kernel-svn-changes
mailing list