aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorEmil Tantilov <emil.s.tantilov@intel.com>2015-01-27 22:21:29 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-02-05 22:58:45 -0500
commite66c92ad5839ffd0ffd0ac7f7afd622151ef6272 (patch)
tree4426f92f300dd26c7a9c5692f5e2c99aab36163e /drivers/net/ethernet
parente08400b707739f0eca1645413924743466ea70b8 (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.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c187
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
2236static int ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, 2238static 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)
2714static void ixgbevf_watchdog(unsigned long data) 2717static 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
2725static 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 */
2749static 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
2744watchdog_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 **/
2781static 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
2748static 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 **/
2809static 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 **/
2834static 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
2846pf_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))