Commit 84c335b0 authored by Scott Feldman's avatar Scott Feldman Committed by Jeff Garzik

e1000 net driver update 5/6:

o Bug fix: moved tx_timeout processing from interrupt context 
  to process context so h/w controller reset can busy-wait.
parent beba7ab7
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/tqueue.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
...@@ -158,6 +159,7 @@ struct e1000_adapter { ...@@ -158,6 +159,7 @@ struct e1000_adapter {
uint16_t link_duplex; uint16_t link_duplex;
spinlock_t stats_lock; spinlock_t stats_lock;
atomic_t irq_sem; atomic_t irq_sem;
struct tq_struct tx_timeout_task;
struct timer_list blink_timer; struct timer_list blink_timer;
unsigned long led_status; unsigned long led_status;
......
...@@ -165,6 +165,7 @@ static inline void e1000_rx_checksum(struct e1000_adapter *adapter, ...@@ -165,6 +165,7 @@ static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
struct e1000_rx_desc *rx_desc, struct e1000_rx_desc *rx_desc,
struct sk_buff *skb); struct sk_buff *skb);
static void e1000_tx_timeout(struct net_device *dev); 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_register(struct net_device *netdev, struct vlan_group *grp);
static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
...@@ -453,6 +454,9 @@ e1000_probe(struct pci_dev *pdev, ...@@ -453,6 +454,9 @@ e1000_probe(struct pci_dev *pdev,
adapter->phy_info_timer.function = &e1000_update_phy_info; adapter->phy_info_timer.function = &e1000_update_phy_info;
adapter->phy_info_timer.data = (unsigned long) adapter; adapter->phy_info_timer.data = (unsigned long) adapter;
INIT_TQUEUE(&adapter->tx_timeout_task,
(void (*)(void *))e1000_tx_timeout_task, netdev);
register_netdev(netdev); register_netdev(netdev);
/* we're going to reset, so assume we have no link for now */ /* we're going to reset, so assume we have no link for now */
...@@ -1455,8 +1459,19 @@ e1000_tx_timeout(struct net_device *netdev) ...@@ -1455,8 +1459,19 @@ e1000_tx_timeout(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; 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_down(adapter);
e1000_up(adapter); e1000_up(adapter);
netif_device_attach(netdev);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment