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 | |
| 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>
| -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 | { | ||
