diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_main.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d1e52b5cebfa..dbb20e57f660 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -833,7 +833,19 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring) | |||
833 | #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \ | 833 | #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \ |
834 | MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */ | 834 | MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */ |
835 | 835 | ||
836 | static void ixgbe_tx_timeout(struct net_device *netdev); | 836 | /** |
837 | * ixgbe_tx_timeout_reset - initiate reset due to Tx timeout | ||
838 | * @adapter: driver private struct | ||
839 | **/ | ||
840 | static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter) | ||
841 | { | ||
842 | |||
843 | /* Do the reset outside of interrupt context */ | ||
844 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) { | ||
845 | adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; | ||
846 | ixgbe_service_event_schedule(adapter); | ||
847 | } | ||
848 | } | ||
837 | 849 | ||
838 | /** | 850 | /** |
839 | * ixgbe_clean_tx_irq - Reclaim resources after transmit completes | 851 | * ixgbe_clean_tx_irq - Reclaim resources after transmit completes |
@@ -915,7 +927,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, | |||
915 | adapter->tx_timeout_count + 1, tx_ring->queue_index); | 927 | adapter->tx_timeout_count + 1, tx_ring->queue_index); |
916 | 928 | ||
917 | /* schedule immediate reset if we believe we hung */ | 929 | /* schedule immediate reset if we believe we hung */ |
918 | ixgbe_tx_timeout(adapter->netdev); | 930 | ixgbe_tx_timeout_reset(adapter); |
919 | 931 | ||
920 | /* the adapter is about to reset, no point in enabling stuff */ | 932 | /* the adapter is about to reset, no point in enabling stuff */ |
921 | return true; | 933 | return true; |
@@ -4186,6 +4198,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
4186 | 4198 | ||
4187 | ixgbe_napi_disable_all(adapter); | 4199 | ixgbe_napi_disable_all(adapter); |
4188 | 4200 | ||
4201 | adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED; | ||
4189 | adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; | 4202 | adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; |
4190 | 4203 | ||
4191 | del_timer_sync(&adapter->service_timer); | 4204 | del_timer_sync(&adapter->service_timer); |
@@ -4288,25 +4301,8 @@ static void ixgbe_tx_timeout(struct net_device *netdev) | |||
4288 | { | 4301 | { |
4289 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 4302 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
4290 | 4303 | ||
4291 | adapter->tx_timeout_count++; | ||
4292 | |||
4293 | /* Do the reset outside of interrupt context */ | 4304 | /* Do the reset outside of interrupt context */ |
4294 | schedule_work(&adapter->reset_task); | 4305 | ixgbe_tx_timeout_reset(adapter); |
4295 | } | ||
4296 | |||
4297 | static void ixgbe_reset_task(struct work_struct *work) | ||
4298 | { | ||
4299 | struct ixgbe_adapter *adapter; | ||
4300 | adapter = container_of(work, struct ixgbe_adapter, reset_task); | ||
4301 | |||
4302 | /* If we're already down or resetting, just bail */ | ||
4303 | if (test_bit(__IXGBE_DOWN, &adapter->state) || | ||
4304 | test_bit(__IXGBE_RESETTING, &adapter->state)) | ||
4305 | return; | ||
4306 | |||
4307 | ixgbe_dump(adapter); | ||
4308 | netdev_err(adapter->netdev, "Reset adapter\n"); | ||
4309 | ixgbe_reinit_locked(adapter); | ||
4310 | } | 4306 | } |
4311 | 4307 | ||
4312 | /** | 4308 | /** |
@@ -6174,7 +6170,7 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter) | |||
6174 | * to get done, so reset controller to flush Tx. | 6170 | * to get done, so reset controller to flush Tx. |
6175 | * (Do the reset outside of interrupt context). | 6171 | * (Do the reset outside of interrupt context). |
6176 | */ | 6172 | */ |
6177 | schedule_work(&adapter->reset_task); | 6173 | adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; |
6178 | } | 6174 | } |
6179 | } | 6175 | } |
6180 | } | 6176 | } |
@@ -6341,6 +6337,25 @@ static void ixgbe_service_timer(unsigned long data) | |||
6341 | ixgbe_service_event_schedule(adapter); | 6337 | ixgbe_service_event_schedule(adapter); |
6342 | } | 6338 | } |
6343 | 6339 | ||
6340 | static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter) | ||
6341 | { | ||
6342 | if (!(adapter->flags2 & IXGBE_FLAG2_RESET_REQUESTED)) | ||
6343 | return; | ||
6344 | |||
6345 | adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED; | ||
6346 | |||
6347 | /* If we're already down or resetting, just bail */ | ||
6348 | if (test_bit(__IXGBE_DOWN, &adapter->state) || | ||
6349 | test_bit(__IXGBE_RESETTING, &adapter->state)) | ||
6350 | return; | ||
6351 | |||
6352 | ixgbe_dump(adapter); | ||
6353 | netdev_err(adapter->netdev, "Reset adapter\n"); | ||
6354 | adapter->tx_timeout_count++; | ||
6355 | |||
6356 | ixgbe_reinit_locked(adapter); | ||
6357 | } | ||
6358 | |||
6344 | /** | 6359 | /** |
6345 | * ixgbe_service_task - manages and runs subtasks | 6360 | * ixgbe_service_task - manages and runs subtasks |
6346 | * @work: pointer to work_struct containing our data | 6361 | * @work: pointer to work_struct containing our data |
@@ -6351,6 +6366,7 @@ static void ixgbe_service_task(struct work_struct *work) | |||
6351 | struct ixgbe_adapter, | 6366 | struct ixgbe_adapter, |
6352 | service_task); | 6367 | service_task); |
6353 | 6368 | ||
6369 | ixgbe_reset_subtask(adapter); | ||
6354 | ixgbe_sfp_detection_subtask(adapter); | 6370 | ixgbe_sfp_detection_subtask(adapter); |
6355 | ixgbe_sfp_link_config_subtask(adapter); | 6371 | ixgbe_sfp_link_config_subtask(adapter); |
6356 | ixgbe_watchdog_subtask(adapter); | 6372 | ixgbe_watchdog_subtask(adapter); |
@@ -7533,8 +7549,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
7533 | setup_timer(&adapter->service_timer, &ixgbe_service_timer, | 7549 | setup_timer(&adapter->service_timer, &ixgbe_service_timer, |
7534 | (unsigned long) adapter); | 7550 | (unsigned long) adapter); |
7535 | 7551 | ||
7536 | INIT_WORK(&adapter->reset_task, ixgbe_reset_task); | ||
7537 | |||
7538 | INIT_WORK(&adapter->service_task, ixgbe_service_task); | 7552 | INIT_WORK(&adapter->service_task, ixgbe_service_task); |
7539 | clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state); | 7553 | clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state); |
7540 | 7554 | ||