diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2008-09-11 20:00:16 -0700 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-24 18:55:00 -0400 |
commit | 7f8218752a76bb1f70b5e4e918f49bc5bf33275a (patch) | |
tree | 6b28066e27a820f193229870d7f3986f4a90ea65 /drivers/net/ixgbe | |
parent | c44ade9ef8ffd73cb8b026065ade78bc0040f0b4 (diff) |
ixgbe: refresh the ixgbe_down function
clean up the hardware shutdown sequence to prevent hardware
from continuing to send when resetting or unloading.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index df093ec830de..cafb915bc828 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1096,7 +1096,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget) r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); rx_ring = &(adapter->rx_ring[r_idx]); /* If all Rx work done, exit the polling mode */ - if ((work_done == 0) || !netif_running(netdev)) { + if (work_done < budget) { netif_rx_complete(netdev, napi); if (adapter->itr_setting & 3) ixgbe_set_itr_msix(q_vector); @@ -2174,32 +2174,41 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter) void ixgbe_down(struct ixgbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; u32 rxctrl; + u32 txdctl; + int i, j; /* signal that we are down to the interrupt handler */ set_bit(__IXGBE_DOWN, &adapter->state); /* disable receives */ - rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, - rxctrl & ~IXGBE_RXCTRL_RXEN); + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); netif_tx_disable(netdev); - /* disable transmits in the hardware */ - - /* flush both disables */ - IXGBE_WRITE_FLUSH(&adapter->hw); + IXGBE_WRITE_FLUSH(hw); msleep(10); + netif_tx_stop_all_queues(netdev); + ixgbe_irq_disable(adapter); ixgbe_napi_disable_all(adapter); + del_timer_sync(&adapter->watchdog_timer); cancel_work_sync(&adapter->watchdog_task); + /* disable transmits in the hardware now that interrupts are off */ + for (i = 0; i < adapter->num_tx_queues; i++) { + j = adapter->tx_ring[i].reg_idx; + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), + (txdctl & ~IXGBE_TXDCTL_ENABLE)); + } + netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { @@ -2219,7 +2228,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) adapter->flags |= IXGBE_FLAG_DCA_ENABLED; /* always use CB2 mode, difference is masked * in the CB driver */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2); + IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2); ixgbe_setup_dca(adapter); } #endif |