|
@@ -283,13 +283,15 @@ ixgb_up(struct ixgb_adapter *adapter)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- mod_timer(&adapter->watchdog_timer, jiffies);
|
|
|
+ clear_bit(__IXGB_DOWN, &adapter->flags);
|
|
|
|
|
|
#ifdef CONFIG_IXGB_NAPI
|
|
|
napi_enable(&adapter->napi);
|
|
|
#endif
|
|
|
ixgb_irq_enable(adapter);
|
|
|
|
|
|
+ mod_timer(&adapter->watchdog_timer, jiffies);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -298,11 +300,14 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
|
|
|
{
|
|
|
struct net_device *netdev = adapter->netdev;
|
|
|
|
|
|
+ /* prevent the interrupt handler from restarting watchdog */
|
|
|
+ set_bit(__IXGB_DOWN, &adapter->flags);
|
|
|
+
|
|
|
#ifdef CONFIG_IXGB_NAPI
|
|
|
napi_disable(&adapter->napi);
|
|
|
atomic_set(&adapter->irq_sem, 0);
|
|
|
#endif
|
|
|
-
|
|
|
+ /* waiting for NAPI to complete can re-enable interrupts */
|
|
|
ixgb_irq_disable(adapter);
|
|
|
free_irq(adapter->pdev->irq, netdev);
|
|
|
|
|
@@ -592,6 +597,7 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
|
|
|
atomic_set(&adapter->irq_sem, 1);
|
|
|
spin_lock_init(&adapter->tx_lock);
|
|
|
|
|
|
+ set_bit(__IXGB_DOWN, &adapter->flags);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1464,14 +1470,18 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|
|
int vlan_id = 0;
|
|
|
int tso;
|
|
|
|
|
|
+ if (test_bit(__IXGB_DOWN, &adapter->flags)) {
|
|
|
+ dev_kfree_skb(skb);
|
|
|
+ return NETDEV_TX_OK;
|
|
|
+ }
|
|
|
+
|
|
|
if(skb->len <= 0) {
|
|
|
dev_kfree_skb_any(skb);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
#ifdef NETIF_F_LLTX
|
|
|
- local_irq_save(flags);
|
|
|
- if (!spin_trylock(&adapter->tx_lock)) {
|
|
|
+ if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
|
|
|
/* Collision - tell upper layer to requeue */
|
|
|
local_irq_restore(flags);
|
|
|
return NETDEV_TX_LOCKED;
|
|
@@ -1753,9 +1763,9 @@ ixgb_intr(int irq, void *data)
|
|
|
if(unlikely(!icr))
|
|
|
return IRQ_NONE; /* Not our interrupt */
|
|
|
|
|
|
- if(unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
|
|
|
- mod_timer(&adapter->watchdog_timer, jiffies);
|
|
|
- }
|
|
|
+ if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)))
|
|
|
+ if (!test_bit(__IXGB_DOWN, &adapter->flags))
|
|
|
+ mod_timer(&adapter->watchdog_timer, jiffies);
|
|
|
|
|
|
#ifdef CONFIG_IXGB_NAPI
|
|
|
if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
|
|
@@ -2195,7 +2205,9 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
|
|
|
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
|
|
|
}
|
|
|
|
|
|
- ixgb_irq_enable(adapter);
|
|
|
+ /* don't enable interrupts unless we are UP */
|
|
|
+ if (adapter->netdev->flags & IFF_UP)
|
|
|
+ ixgb_irq_enable(adapter);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -2222,9 +2234,11 @@ ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
|
|
|
|
|
|
vlan_group_set_device(adapter->vlgrp, vid, NULL);
|
|
|
|
|
|
- ixgb_irq_enable(adapter);
|
|
|
+ /* don't enable interrupts unless we are UP */
|
|
|
+ if (adapter->netdev->flags & IFF_UP)
|
|
|
+ ixgb_irq_enable(adapter);
|
|
|
|
|
|
- /* remove VID from filter table*/
|
|
|
+ /* remove VID from filter table */
|
|
|
|
|
|
index = (vid >> 5) & 0x7F;
|
|
|
vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index);
|