From ea1a1c41ec03f78a5d7e0ec4d1b2ec896e697ecc Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 31 Jul 2009 01:57:42 +0000 Subject: [PATCH] --- yaml --- r: 156353 b: refs/heads/master c: f6caa14aa0b126d4a2933907d1519611b2a8524a h: refs/heads/master i: 156351: 9d7f6dadf2fc8cebfc67822326e3ae1dcbf7d496 v: v3 --- [refs] | 2 +- trunk/drivers/net/sky2.c | 14 +++++++++++++- trunk/drivers/net/sky2.h | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index d8f574bb87c3..6992f7b69e30 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 202ff1ec8e53d5dd36e1a5bd4b0a7ed7dbd45087 +refs/heads/master: f6caa14aa0b126d4a2933907d1519611b2a8524a diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 3550c5dcd93c..0a551d8f5d95 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -1488,6 +1488,8 @@ static int sky2_up(struct net_device *dev) sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL); #endif + sky2->restarting = 0; + err = sky2_rx_start(sky2); if (err) goto err_out; @@ -1500,6 +1502,9 @@ static int sky2_up(struct net_device *dev) sky2_set_multicast(dev); + /* wake queue incase we are restarting */ + netif_wake_queue(dev); + if (netif_msg_ifup(sky2)) printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); return 0; @@ -1533,6 +1538,8 @@ static inline int tx_dist(unsigned tail, unsigned head) /* Number of list elements available for next tx */ static inline int tx_avail(const struct sky2_port *sky2) { + if (unlikely(sky2->restarting)) + return 0; return sky2->tx_pending - tx_dist(sky2->tx_cons, sky2->tx_prod); } @@ -1818,6 +1825,10 @@ static int sky2_down(struct net_device *dev) if (netif_msg_ifdown(sky2)) printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); + /* explicitly shut off tx incase we're restarting */ + sky2->restarting = 1; + netif_tx_disable(dev); + /* Force flow control off */ sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); @@ -2359,7 +2370,7 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) { struct sky2_port *sky2 = netdev_priv(dev); - if (netif_running(dev)) { + if (likely(netif_running(dev) && !sky2->restarting)) { netif_tx_lock(dev); sky2_tx_complete(sky2, last); netif_tx_unlock(dev); @@ -4283,6 +4294,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, spin_lock_init(&sky2->phy_lock); sky2->tx_pending = TX_DEF_PENDING; sky2->rx_pending = RX_DEF_PENDING; + sky2->restarting = 0; hw->dev[port] = dev; diff --git a/trunk/drivers/net/sky2.h b/trunk/drivers/net/sky2.h index b5549c9e5107..4486b066b43f 100644 --- a/trunk/drivers/net/sky2.h +++ b/trunk/drivers/net/sky2.h @@ -2051,6 +2051,7 @@ struct sky2_port { u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ u8 rx_csum; u8 wol; + u8 restarting; enum flow_control flow_mode; enum flow_control flow_status;