diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2008-09-11 23:00:16 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-24 18:55:00 -0400 |
commit | 7f8218752a76bb1f70b5e4e918f49bc5bf33275a (patch) | |
tree | 6b28066e27a820f193229870d7f3986f4a90ea65 | |
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>
-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) | |||
1096 | r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); | 1096 | r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); |
1097 | rx_ring = &(adapter->rx_ring[r_idx]); | 1097 | rx_ring = &(adapter->rx_ring[r_idx]); |
1098 | /* If all Rx work done, exit the polling mode */ | 1098 | /* If all Rx work done, exit the polling mode */ |
1099 | if ((work_done == 0) || !netif_running(netdev)) { | 1099 | if (work_done < budget) { |
1100 | netif_rx_complete(netdev, napi); | 1100 | netif_rx_complete(netdev, napi); |
1101 | if (adapter->itr_setting & 3) | 1101 | if (adapter->itr_setting & 3) |
1102 | ixgbe_set_itr_msix(q_vector); | 1102 | ixgbe_set_itr_msix(q_vector); |
@@ -2174,32 +2174,41 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter) | |||
2174 | void ixgbe_down(struct ixgbe_adapter *adapter) | 2174 | void ixgbe_down(struct ixgbe_adapter *adapter) |
2175 | { | 2175 | { |
2176 | struct net_device *netdev = adapter->netdev; | 2176 | struct net_device *netdev = adapter->netdev; |
2177 | struct ixgbe_hw *hw = &adapter->hw; | ||
2177 | u32 rxctrl; | 2178 | u32 rxctrl; |
2179 | u32 txdctl; | ||
2180 | int i, j; | ||
2178 | 2181 | ||
2179 | /* signal that we are down to the interrupt handler */ | 2182 | /* signal that we are down to the interrupt handler */ |
2180 | set_bit(__IXGBE_DOWN, &adapter->state); | 2183 | set_bit(__IXGBE_DOWN, &adapter->state); |
2181 | 2184 | ||
2182 | /* disable receives */ | 2185 | /* disable receives */ |
2183 | rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL); | 2186 | rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); |
2184 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, | 2187 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); |
2185 | rxctrl & ~IXGBE_RXCTRL_RXEN); | ||
2186 | 2188 | ||
2187 | netif_tx_disable(netdev); | 2189 | netif_tx_disable(netdev); |
2188 | 2190 | ||
2189 | /* disable transmits in the hardware */ | 2191 | IXGBE_WRITE_FLUSH(hw); |
2190 | |||
2191 | /* flush both disables */ | ||
2192 | IXGBE_WRITE_FLUSH(&adapter->hw); | ||
2193 | msleep(10); | 2192 | msleep(10); |
2194 | 2193 | ||
2194 | netif_tx_stop_all_queues(netdev); | ||
2195 | |||
2195 | ixgbe_irq_disable(adapter); | 2196 | ixgbe_irq_disable(adapter); |
2196 | 2197 | ||
2197 | ixgbe_napi_disable_all(adapter); | 2198 | ixgbe_napi_disable_all(adapter); |
2199 | |||
2198 | del_timer_sync(&adapter->watchdog_timer); | 2200 | del_timer_sync(&adapter->watchdog_timer); |
2199 | cancel_work_sync(&adapter->watchdog_task); | 2201 | cancel_work_sync(&adapter->watchdog_task); |
2200 | 2202 | ||
2203 | /* disable transmits in the hardware now that interrupts are off */ | ||
2204 | for (i = 0; i < adapter->num_tx_queues; i++) { | ||
2205 | j = adapter->tx_ring[i].reg_idx; | ||
2206 | txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); | ||
2207 | IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), | ||
2208 | (txdctl & ~IXGBE_TXDCTL_ENABLE)); | ||
2209 | } | ||
2210 | |||
2201 | netif_carrier_off(netdev); | 2211 | netif_carrier_off(netdev); |
2202 | netif_tx_stop_all_queues(netdev); | ||
2203 | 2212 | ||
2204 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | 2213 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) |
2205 | if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { | 2214 | if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { |
@@ -2219,7 +2228,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
2219 | adapter->flags |= IXGBE_FLAG_DCA_ENABLED; | 2228 | adapter->flags |= IXGBE_FLAG_DCA_ENABLED; |
2220 | /* always use CB2 mode, difference is masked | 2229 | /* always use CB2 mode, difference is masked |
2221 | * in the CB driver */ | 2230 | * in the CB driver */ |
2222 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2); | 2231 | IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2); |
2223 | ixgbe_setup_dca(adapter); | 2232 | ixgbe_setup_dca(adapter); |
2224 | } | 2233 | } |
2225 | #endif | 2234 | #endif |