Commit bab2bce7 authored by Jesse Brandeburg's avatar Jesse Brandeburg Committed by Jeff Garzik
Browse files

ixgb: add explicit state checking



In order to remove the irq_sem code we need to implement strict
adapter state checking to prevent accidental double up or downs
or resets. This code is largely copied from e1000/e1000e.

Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: default avatarAuke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent c3033b01
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -195,6 +195,15 @@ struct ixgb_adapter {
	struct ixgb_hw_stats stats;
	uint32_t alloc_rx_buff_failed;
	boolean_t have_msi;
	unsigned long flags;
};

enum ixgb_state_t {
	/* TBD
	__IXGB_TESTING,
	__IXGB_RESETTING,
	*/
	__IXGB_DOWN
};

/* Exported from other modules */
+24 −10
Original line number Diff line number Diff line
@@ -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))) {
	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,6 +2205,8 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
		IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
	}

	/* don't enable interrupts unless we are UP */
	if (adapter->netdev->flags & IFF_UP)
		ixgb_irq_enable(adapter);
}

@@ -2222,6 +2234,8 @@ ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)

	vlan_group_set_device(adapter->vlgrp, vid, NULL);

	/* don't enable interrupts unless we are UP */
	if (adapter->netdev->flags & IFF_UP)
		ixgb_irq_enable(adapter);

	/* remove VID from filter table */