diff options
author | Emil Tantilov <emil.s.tantilov@intel.com> | 2015-01-27 22:21:29 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2015-02-05 22:58:45 -0500 |
commit | e66c92ad5839ffd0ffd0ac7f7afd622151ef6272 (patch) | |
tree | 4426f92f300dd26c7a9c5692f5e2c99aab36163e /drivers/net/ethernet | |
parent | e08400b707739f0eca1645413924743466ea70b8 (diff) |
ixgbevf: rewrite watchdog task to function similar to igbvf
This patch cleans up the logic dealing with link down/up by breaking down the
link detection and up/down events into separate functions - similar to how these
events are handled in other drivers.
CC: Alexander Duyck <alexander.h.duyck@redhat.com>
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 187 |
2 files changed, 113 insertions, 75 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 65c2aee2a083..a41ab370278f 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | |||
@@ -436,6 +436,7 @@ struct ixgbevf_adapter { | |||
436 | bool link_up; | 436 | bool link_up; |
437 | 437 | ||
438 | spinlock_t mbx_lock; | 438 | spinlock_t mbx_lock; |
439 | unsigned long last_reset; | ||
439 | 440 | ||
440 | struct work_struct watchdog_task; | 441 | struct work_struct watchdog_task; |
441 | }; | 442 | }; |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 87f9f8686b6f..c1100654a4be 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -2231,6 +2231,8 @@ void ixgbevf_reset(struct ixgbevf_adapter *adapter) | |||
2231 | memcpy(netdev->perm_addr, adapter->hw.mac.addr, | 2231 | memcpy(netdev->perm_addr, adapter->hw.mac.addr, |
2232 | netdev->addr_len); | 2232 | netdev->addr_len); |
2233 | } | 2233 | } |
2234 | |||
2235 | adapter->last_reset = jiffies; | ||
2234 | } | 2236 | } |
2235 | 2237 | ||
2236 | static int ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, | 2238 | static int ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, |
@@ -2684,7 +2686,8 @@ void ixgbevf_update_stats(struct ixgbevf_adapter *adapter) | |||
2684 | struct ixgbe_hw *hw = &adapter->hw; | 2686 | struct ixgbe_hw *hw = &adapter->hw; |
2685 | int i; | 2687 | int i; |
2686 | 2688 | ||
2687 | if (!adapter->link_up) | 2689 | if (test_bit(__IXGBEVF_DOWN, &adapter->state) || |
2690 | test_bit(__IXGBEVF_RESETTING, &adapter->state)) | ||
2688 | return; | 2691 | return; |
2689 | 2692 | ||
2690 | UPDATE_VF_COUNTER_32bit(IXGBE_VFGPRC, adapter->stats.last_vfgprc, | 2693 | UPDATE_VF_COUNTER_32bit(IXGBE_VFGPRC, adapter->stats.last_vfgprc, |
@@ -2714,17 +2717,45 @@ void ixgbevf_update_stats(struct ixgbevf_adapter *adapter) | |||
2714 | static void ixgbevf_watchdog(unsigned long data) | 2717 | static void ixgbevf_watchdog(unsigned long data) |
2715 | { | 2718 | { |
2716 | struct ixgbevf_adapter *adapter = (struct ixgbevf_adapter *)data; | 2719 | struct ixgbevf_adapter *adapter = (struct ixgbevf_adapter *)data; |
2720 | |||
2721 | /* Do the reset outside of interrupt context */ | ||
2722 | schedule_work(&adapter->watchdog_task); | ||
2723 | } | ||
2724 | |||
2725 | static void ixgbevf_reset_task(struct work_struct *work) | ||
2726 | { | ||
2727 | struct ixgbevf_adapter *adapter; | ||
2728 | |||
2729 | adapter = container_of(work, struct ixgbevf_adapter, reset_task); | ||
2730 | |||
2731 | /* If we're already down or resetting, just bail */ | ||
2732 | if (test_bit(__IXGBEVF_DOWN, &adapter->state) || | ||
2733 | test_bit(__IXGBEVF_RESETTING, &adapter->state)) | ||
2734 | return; | ||
2735 | |||
2736 | adapter->tx_timeout_count++; | ||
2737 | |||
2738 | ixgbevf_reinit_locked(adapter); | ||
2739 | } | ||
2740 | |||
2741 | /* ixgbevf_check_hang_subtask - check for hung queues and dropped interrupts | ||
2742 | * @adapter - pointer to the device adapter structure | ||
2743 | * | ||
2744 | * This function serves two purposes. First it strobes the interrupt lines | ||
2745 | * in order to make certain interrupts are occurring. Secondly it sets the | ||
2746 | * bits needed to check for TX hangs. As a result we should immediately | ||
2747 | * determine if a hang has occurred. | ||
2748 | */ | ||
2749 | static void ixgbevf_check_hang_subtask(struct ixgbevf_adapter *adapter) | ||
2750 | { | ||
2717 | struct ixgbe_hw *hw = &adapter->hw; | 2751 | struct ixgbe_hw *hw = &adapter->hw; |
2718 | u32 eics = 0; | 2752 | u32 eics = 0; |
2719 | int i; | 2753 | int i; |
2720 | 2754 | ||
2721 | /* | 2755 | /* If we're down or resetting, just bail */ |
2722 | * Do the watchdog outside of interrupt context due to the lovely | 2756 | if (test_bit(__IXGBEVF_DOWN, &adapter->state) || |
2723 | * delays that some of the newer hardware requires | 2757 | test_bit(__IXGBEVF_RESETTING, &adapter->state)) |
2724 | */ | 2758 | return; |
2725 | |||
2726 | if (test_bit(__IXGBEVF_DOWN, &adapter->state)) | ||
2727 | goto watchdog_short_circuit; | ||
2728 | 2759 | ||
2729 | /* Force detection of hung controller */ | 2760 | /* Force detection of hung controller */ |
2730 | if (netif_carrier_ok(adapter->netdev)) { | 2761 | if (netif_carrier_ok(adapter->netdev)) { |
@@ -2739,26 +2770,80 @@ static void ixgbevf_watchdog(unsigned long data) | |||
2739 | eics |= 1 << i; | 2770 | eics |= 1 << i; |
2740 | } | 2771 | } |
2741 | 2772 | ||
2773 | /* Cause software interrupt to ensure rings are cleaned */ | ||
2742 | IXGBE_WRITE_REG(hw, IXGBE_VTEICS, eics); | 2774 | IXGBE_WRITE_REG(hw, IXGBE_VTEICS, eics); |
2775 | } | ||
2743 | 2776 | ||
2744 | watchdog_short_circuit: | 2777 | /** |
2745 | schedule_work(&adapter->watchdog_task); | 2778 | * ixgbevf_watchdog_update_link - update the link status |
2779 | * @adapter - pointer to the device adapter structure | ||
2780 | **/ | ||
2781 | static void ixgbevf_watchdog_update_link(struct ixgbevf_adapter *adapter) | ||
2782 | { | ||
2783 | struct ixgbe_hw *hw = &adapter->hw; | ||
2784 | u32 link_speed = adapter->link_speed; | ||
2785 | bool link_up = adapter->link_up; | ||
2786 | s32 err; | ||
2787 | |||
2788 | spin_lock_bh(&adapter->mbx_lock); | ||
2789 | |||
2790 | err = hw->mac.ops.check_link(hw, &link_speed, &link_up, false); | ||
2791 | |||
2792 | spin_unlock_bh(&adapter->mbx_lock); | ||
2793 | |||
2794 | /* if check for link returns error we will need to reset */ | ||
2795 | if (err && time_after(jiffies, adapter->last_reset + (10 * HZ))) { | ||
2796 | schedule_work(&adapter->reset_task); | ||
2797 | link_up = false; | ||
2798 | } | ||
2799 | |||
2800 | adapter->link_up = link_up; | ||
2801 | adapter->link_speed = link_speed; | ||
2746 | } | 2802 | } |
2747 | 2803 | ||
2748 | static void ixgbevf_reset_task(struct work_struct *work) | 2804 | /** |
2805 | * ixgbevf_watchdog_link_is_up - update netif_carrier status and | ||
2806 | * print link up message | ||
2807 | * @adapter - pointer to the device adapter structure | ||
2808 | **/ | ||
2809 | static void ixgbevf_watchdog_link_is_up(struct ixgbevf_adapter *adapter) | ||
2749 | { | 2810 | { |
2750 | struct ixgbevf_adapter *adapter; | 2811 | struct net_device *netdev = adapter->netdev; |
2751 | adapter = container_of(work, struct ixgbevf_adapter, reset_task); | ||
2752 | 2812 | ||
2753 | /* If we're already down or resetting, just bail */ | 2813 | /* only continue if link was previously down */ |
2754 | if (test_bit(__IXGBEVF_DOWN, &adapter->state) || | 2814 | if (netif_carrier_ok(netdev)) |
2755 | test_bit(__IXGBEVF_REMOVING, &adapter->state) || | ||
2756 | test_bit(__IXGBEVF_RESETTING, &adapter->state)) | ||
2757 | return; | 2815 | return; |
2758 | 2816 | ||
2759 | adapter->tx_timeout_count++; | 2817 | dev_info(&adapter->pdev->dev, "NIC Link is Up %s\n", |
2818 | (adapter->link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? | ||
2819 | "10 Gbps" : | ||
2820 | (adapter->link_speed == IXGBE_LINK_SPEED_1GB_FULL) ? | ||
2821 | "1 Gbps" : | ||
2822 | (adapter->link_speed == IXGBE_LINK_SPEED_100_FULL) ? | ||
2823 | "100 Mbps" : | ||
2824 | "unknown speed"); | ||
2760 | 2825 | ||
2761 | ixgbevf_reinit_locked(adapter); | 2826 | netif_carrier_on(netdev); |
2827 | } | ||
2828 | |||
2829 | /** | ||
2830 | * ixgbevf_watchdog_link_is_down - update netif_carrier status and | ||
2831 | * print link down message | ||
2832 | * @adapter - pointer to the adapter structure | ||
2833 | **/ | ||
2834 | static void ixgbevf_watchdog_link_is_down(struct ixgbevf_adapter *adapter) | ||
2835 | { | ||
2836 | struct net_device *netdev = adapter->netdev; | ||
2837 | |||
2838 | adapter->link_speed = 0; | ||
2839 | |||
2840 | /* only continue if link was up previously */ | ||
2841 | if (!netif_carrier_ok(netdev)) | ||
2842 | return; | ||
2843 | |||
2844 | dev_info(&adapter->pdev->dev, "NIC Link is Down\n"); | ||
2845 | |||
2846 | netif_carrier_off(netdev); | ||
2762 | } | 2847 | } |
2763 | 2848 | ||
2764 | /** | 2849 | /** |
@@ -2770,11 +2855,7 @@ static void ixgbevf_watchdog_task(struct work_struct *work) | |||
2770 | struct ixgbevf_adapter *adapter = container_of(work, | 2855 | struct ixgbevf_adapter *adapter = container_of(work, |
2771 | struct ixgbevf_adapter, | 2856 | struct ixgbevf_adapter, |
2772 | watchdog_task); | 2857 | watchdog_task); |
2773 | struct net_device *netdev = adapter->netdev; | ||
2774 | struct ixgbe_hw *hw = &adapter->hw; | 2858 | struct ixgbe_hw *hw = &adapter->hw; |
2775 | u32 link_speed = adapter->link_speed; | ||
2776 | bool link_up = adapter->link_up; | ||
2777 | s32 need_reset; | ||
2778 | 2859 | ||
2779 | if (IXGBE_REMOVED(hw->hw_addr)) { | 2860 | if (IXGBE_REMOVED(hw->hw_addr)) { |
2780 | if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) { | 2861 | if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) { |
@@ -2784,66 +2865,22 @@ static void ixgbevf_watchdog_task(struct work_struct *work) | |||
2784 | } | 2865 | } |
2785 | return; | 2866 | return; |
2786 | } | 2867 | } |
2868 | |||
2787 | ixgbevf_queue_reset_subtask(adapter); | 2869 | ixgbevf_queue_reset_subtask(adapter); |
2788 | 2870 | ||
2789 | adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK; | 2871 | adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK; |
2790 | 2872 | ||
2791 | /* | 2873 | ixgbevf_watchdog_update_link(adapter); |
2792 | * Always check the link on the watchdog because we have | ||
2793 | * no LSC interrupt | ||
2794 | */ | ||
2795 | spin_lock_bh(&adapter->mbx_lock); | ||
2796 | |||
2797 | need_reset = hw->mac.ops.check_link(hw, &link_speed, &link_up, false); | ||
2798 | |||
2799 | spin_unlock_bh(&adapter->mbx_lock); | ||
2800 | |||
2801 | if (need_reset) { | ||
2802 | adapter->link_up = link_up; | ||
2803 | adapter->link_speed = link_speed; | ||
2804 | netif_carrier_off(netdev); | ||
2805 | netif_tx_stop_all_queues(netdev); | ||
2806 | schedule_work(&adapter->reset_task); | ||
2807 | goto pf_has_reset; | ||
2808 | } | ||
2809 | adapter->link_up = link_up; | ||
2810 | adapter->link_speed = link_speed; | ||
2811 | 2874 | ||
2812 | if (link_up) { | 2875 | if (adapter->link_up) |
2813 | if (!netif_carrier_ok(netdev)) { | 2876 | ixgbevf_watchdog_link_is_up(adapter); |
2814 | char *link_speed_string; | 2877 | else |
2815 | switch (link_speed) { | 2878 | ixgbevf_watchdog_link_is_down(adapter); |
2816 | case IXGBE_LINK_SPEED_10GB_FULL: | ||
2817 | link_speed_string = "10 Gbps"; | ||
2818 | break; | ||
2819 | case IXGBE_LINK_SPEED_1GB_FULL: | ||
2820 | link_speed_string = "1 Gbps"; | ||
2821 | break; | ||
2822 | case IXGBE_LINK_SPEED_100_FULL: | ||
2823 | link_speed_string = "100 Mbps"; | ||
2824 | break; | ||
2825 | default: | ||
2826 | link_speed_string = "unknown speed"; | ||
2827 | break; | ||
2828 | } | ||
2829 | dev_info(&adapter->pdev->dev, | ||
2830 | "NIC Link is Up, %s\n", link_speed_string); | ||
2831 | netif_carrier_on(netdev); | ||
2832 | netif_tx_wake_all_queues(netdev); | ||
2833 | } | ||
2834 | } else { | ||
2835 | adapter->link_up = false; | ||
2836 | adapter->link_speed = 0; | ||
2837 | if (netif_carrier_ok(netdev)) { | ||
2838 | dev_info(&adapter->pdev->dev, "NIC Link is Down\n"); | ||
2839 | netif_carrier_off(netdev); | ||
2840 | netif_tx_stop_all_queues(netdev); | ||
2841 | } | ||
2842 | } | ||
2843 | 2879 | ||
2844 | ixgbevf_update_stats(adapter); | 2880 | ixgbevf_update_stats(adapter); |
2845 | 2881 | ||
2846 | pf_has_reset: | 2882 | ixgbevf_check_hang_subtask(adapter); |
2883 | |||
2847 | /* Reset the timer */ | 2884 | /* Reset the timer */ |
2848 | if (!test_bit(__IXGBEVF_DOWN, &adapter->state) && | 2885 | if (!test_bit(__IXGBEVF_DOWN, &adapter->state) && |
2849 | !test_bit(__IXGBEVF_REMOVING, &adapter->state)) | 2886 | !test_bit(__IXGBEVF_REMOVING, &adapter->state)) |