diff options
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/netdev.c')
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index c6e976302f97..93ae0c26d434 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -1014,6 +1014,7 @@ static void e1000_print_hw_hang(struct work_struct *work) | |||
1014 | struct e1000_adapter *adapter = container_of(work, | 1014 | struct e1000_adapter *adapter = container_of(work, |
1015 | struct e1000_adapter, | 1015 | struct e1000_adapter, |
1016 | print_hang_task); | 1016 | print_hang_task); |
1017 | struct net_device *netdev = adapter->netdev; | ||
1017 | struct e1000_ring *tx_ring = adapter->tx_ring; | 1018 | struct e1000_ring *tx_ring = adapter->tx_ring; |
1018 | unsigned int i = tx_ring->next_to_clean; | 1019 | unsigned int i = tx_ring->next_to_clean; |
1019 | unsigned int eop = tx_ring->buffer_info[i].next_to_watch; | 1020 | unsigned int eop = tx_ring->buffer_info[i].next_to_watch; |
@@ -1025,6 +1026,21 @@ static void e1000_print_hw_hang(struct work_struct *work) | |||
1025 | if (test_bit(__E1000_DOWN, &adapter->state)) | 1026 | if (test_bit(__E1000_DOWN, &adapter->state)) |
1026 | return; | 1027 | return; |
1027 | 1028 | ||
1029 | if (!adapter->tx_hang_recheck && | ||
1030 | (adapter->flags2 & FLAG2_DMA_BURST)) { | ||
1031 | /* May be block on write-back, flush and detect again | ||
1032 | * flush pending descriptor writebacks to memory | ||
1033 | */ | ||
1034 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); | ||
1035 | /* execute the writes immediately */ | ||
1036 | e1e_flush(); | ||
1037 | adapter->tx_hang_recheck = true; | ||
1038 | return; | ||
1039 | } | ||
1040 | /* Real hang detected */ | ||
1041 | adapter->tx_hang_recheck = false; | ||
1042 | netif_stop_queue(netdev); | ||
1043 | |||
1028 | e1e_rphy(hw, PHY_STATUS, &phy_status); | 1044 | e1e_rphy(hw, PHY_STATUS, &phy_status); |
1029 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); | 1045 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); |
1030 | e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); | 1046 | e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); |
@@ -1145,10 +1161,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
1145 | if (tx_ring->buffer_info[i].time_stamp && | 1161 | if (tx_ring->buffer_info[i].time_stamp && |
1146 | time_after(jiffies, tx_ring->buffer_info[i].time_stamp | 1162 | time_after(jiffies, tx_ring->buffer_info[i].time_stamp |
1147 | + (adapter->tx_timeout_factor * HZ)) && | 1163 | + (adapter->tx_timeout_factor * HZ)) && |
1148 | !(er32(STATUS) & E1000_STATUS_TXOFF)) { | 1164 | !(er32(STATUS) & E1000_STATUS_TXOFF)) |
1149 | schedule_work(&adapter->print_hang_task); | 1165 | schedule_work(&adapter->print_hang_task); |
1150 | netif_stop_queue(netdev); | 1166 | else |
1151 | } | 1167 | adapter->tx_hang_recheck = false; |
1152 | } | 1168 | } |
1153 | adapter->total_tx_bytes += total_tx_bytes; | 1169 | adapter->total_tx_bytes += total_tx_bytes; |
1154 | adapter->total_tx_packets += total_tx_packets; | 1170 | adapter->total_tx_packets += total_tx_packets; |
@@ -3500,7 +3516,6 @@ int e1000e_up(struct e1000_adapter *adapter) | |||
3500 | 3516 | ||
3501 | clear_bit(__E1000_DOWN, &adapter->state); | 3517 | clear_bit(__E1000_DOWN, &adapter->state); |
3502 | 3518 | ||
3503 | napi_enable(&adapter->napi); | ||
3504 | if (adapter->msix_entries) | 3519 | if (adapter->msix_entries) |
3505 | e1000_configure_msix(adapter); | 3520 | e1000_configure_msix(adapter); |
3506 | e1000_irq_enable(adapter); | 3521 | e1000_irq_enable(adapter); |
@@ -3562,7 +3577,6 @@ void e1000e_down(struct e1000_adapter *adapter) | |||
3562 | e1e_flush(); | 3577 | e1e_flush(); |
3563 | usleep_range(10000, 20000); | 3578 | usleep_range(10000, 20000); |
3564 | 3579 | ||
3565 | napi_disable(&adapter->napi); | ||
3566 | e1000_irq_disable(adapter); | 3580 | e1000_irq_disable(adapter); |
3567 | 3581 | ||
3568 | del_timer_sync(&adapter->watchdog_timer); | 3582 | del_timer_sync(&adapter->watchdog_timer); |
@@ -3838,6 +3852,7 @@ static int e1000_open(struct net_device *netdev) | |||
3838 | 3852 | ||
3839 | e1000_irq_enable(adapter); | 3853 | e1000_irq_enable(adapter); |
3840 | 3854 | ||
3855 | adapter->tx_hang_recheck = false; | ||
3841 | netif_start_queue(netdev); | 3856 | netif_start_queue(netdev); |
3842 | 3857 | ||
3843 | adapter->idle_check = true; | 3858 | adapter->idle_check = true; |
@@ -3884,6 +3899,8 @@ static int e1000_close(struct net_device *netdev) | |||
3884 | 3899 | ||
3885 | pm_runtime_get_sync(&pdev->dev); | 3900 | pm_runtime_get_sync(&pdev->dev); |
3886 | 3901 | ||
3902 | napi_disable(&adapter->napi); | ||
3903 | |||
3887 | if (!test_bit(__E1000_DOWN, &adapter->state)) { | 3904 | if (!test_bit(__E1000_DOWN, &adapter->state)) { |
3888 | e1000e_down(adapter); | 3905 | e1000e_down(adapter); |
3889 | e1000_free_irq(adapter); | 3906 | e1000_free_irq(adapter); |