diff -Naurp linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000.h linux-2.4.20-pre4-e1000-6/drivers/net/e1000/e1000.h
--- linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000.h	Fri Aug 23 06:55:25 2002
+++ linux-2.4.20-pre4-e1000-6/drivers/net/e1000/e1000.h	Fri Aug 23 07:10:15 2002
@@ -63,6 +63,7 @@
 #include <net/pkt_sched.h>
 #include <linux/list.h>
 #include <linux/reboot.h>
+#include <linux/tqueue.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
 
@@ -158,6 +159,7 @@ struct e1000_adapter {
 	uint16_t link_duplex;
 	spinlock_t stats_lock;
 	atomic_t irq_sem;
+	struct tq_struct tx_timeout_task;
 
 	struct timer_list blink_timer;
 	unsigned long led_status;
diff -Naurp linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_main.c linux-2.4.20-pre4-e1000-6/drivers/net/e1000/e1000_main.c
--- linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_main.c	Fri Aug 23 06:55:25 2002
+++ linux-2.4.20-pre4-e1000-6/drivers/net/e1000/e1000_main.c	Fri Aug 23 07:08:45 2002
@@ -168,6 +168,7 @@ static inline void e1000_rx_checksum(str
 static boolean_t e1000_smbus_arp_enable(struct e1000_adapter *adapter,
 					boolean_t arp_enable);
 static void e1000_tx_timeout(struct net_device *dev);
+static void e1000_tx_timeout_task(struct net_device *dev);
 
 static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
 static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
@@ -462,6 +463,9 @@ e1000_probe(struct pci_dev *pdev,
 	adapter->phy_info_timer.function = &e1000_update_phy_info;
 	adapter->phy_info_timer.data = (unsigned long) adapter;
 
+	INIT_TQUEUE(&adapter->tx_timeout_task, 
+		(void (*)(void *))e1000_tx_timeout_task, netdev);
+
 	register_netdev(netdev);
 
 	/* we're going to reset, so assume we have no link for now */
@@ -1458,8 +1462,19 @@ e1000_tx_timeout(struct net_device *netd
 {
 	struct e1000_adapter *adapter = netdev->priv;
 
+	/* Do the reset outside of interrupt context */
+	schedule_task(&adapter->tx_timeout_task);
+}
+
+static void
+e1000_tx_timeout_task(struct net_device *netdev)
+{
+	struct e1000_adapter *adapter = netdev->priv;
+
+	netif_device_detach(netdev);
 	e1000_down(adapter);
 	e1000_up(adapter);
+	netif_device_attach(netdev);
 }
 
 /**
