[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