diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 8a763f8..a4c2778 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1874,6 +1874,8 @@ static int sky2_down(struct net_device *dev) sky2_rx_stop(sky2); + msleep(1); + /* Disable port IRQ */ imask = sky2_read32(hw, B0_IMSK); imask &= ~portirq_msk[port]; @@ -1881,7 +1883,7 @@ static int sky2_down(struct net_device *dev) sky2_read32(hw, B0_IMSK); synchronize_irq(hw->pdev->irq); - napi_synchronize(&hw->napi); + napi_disable(&hw->napi); spin_lock_bh(&sky2->phy_lock); sky2_phy_power_down(hw, port); @@ -1912,6 +1914,8 @@ static int sky2_down(struct net_device *dev) sky2->rx_ring = NULL; sky2->tx_ring = NULL; + napi_enable(&hw->napi); + return 0; } @@ -2371,7 +2375,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->tx_ring)) sky2_tx_complete(sky2, last); } @@ -2437,6 +2441,12 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) length = le16_to_cpu(le->length); status = le32_to_cpu(le->status); + if (unlikely(!sky2->rx_ring)) { + printk(KERN_INFO PFX "%s: rx ring NULL %08x\n", + dev->name, opcode); + continue; + } + le->opcode = 0; switch (opcode & ~HW_OWNER) { case OP_RXSTAT: