diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2011-04-27 05:13:56 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-05-14 21:01:13 -0400 |
commit | 7086400d87a06588c13270949db9134afc9553ba (patch) | |
tree | 8ee25d42a75d5cf10720837c60f97a2a8eb8d550 /drivers | |
parent | e606bfe74de63d6c3778c145ee0673d96ab257c9 (diff) |
ixgbe: Combine SFP and multi-speed fiber task into single service task
This change is meant to address several race conditions with multi-speed
fiber SFP+ modules in 82599 adapters. Specifically issues have been seen
in which both the SFP configuration and the multi-speed fiber configuration
are running simultaneously which will result in the device getting into an
erroneous link down state.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Evan Swanson <evan.swanson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 26 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 388 |
2 files changed, 213 insertions, 201 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index ec948ffec553..cbb04ba58289 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -367,19 +367,20 @@ struct ixgbe_adapter { | |||
367 | #define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19) | 367 | #define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19) |
368 | #define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20) | 368 | #define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20) |
369 | #define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22) | 369 | #define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22) |
370 | #define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 23) | 370 | #define IXGBE_FLAG_NEED_LINK_CONFIG (u32)(1 << 23) |
371 | #define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 24) | 371 | #define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 24) |
372 | #define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 25) | 372 | #define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 25) |
373 | #define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 26) | 373 | #define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 26) |
374 | #define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 27) | 374 | #define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 27) |
375 | #define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 28) | 375 | #define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 28) |
376 | #define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 29) | 376 | #define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 29) |
377 | #define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 30) | ||
378 | 377 | ||
379 | u32 flags2; | 378 | u32 flags2; |
380 | #define IXGBE_FLAG2_RSC_CAPABLE (u32)(1) | 379 | #define IXGBE_FLAG2_RSC_CAPABLE (u32)(1) |
381 | #define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1) | 380 | #define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1) |
382 | #define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2) | 381 | #define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2) |
382 | #define IXGBE_FLAG2_SEARCH_FOR_SFP (u32)(1 << 4) | ||
383 | #define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 5) | ||
383 | 384 | ||
384 | unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; | 385 | unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; |
385 | u16 bd_number; | 386 | u16 bd_number; |
@@ -455,13 +456,11 @@ struct ixgbe_adapter { | |||
455 | 456 | ||
456 | struct work_struct reset_task; | 457 | struct work_struct reset_task; |
457 | struct work_struct watchdog_task; | 458 | struct work_struct watchdog_task; |
458 | struct work_struct sfp_task; | ||
459 | struct work_struct multispeed_fiber_task; | ||
460 | struct work_struct sfp_config_module_task; | ||
461 | struct work_struct fdir_reinit_task; | 459 | struct work_struct fdir_reinit_task; |
462 | struct work_struct check_overtemp_task; | 460 | struct work_struct check_overtemp_task; |
461 | struct work_struct service_task; | ||
463 | struct timer_list watchdog_timer; | 462 | struct timer_list watchdog_timer; |
464 | struct timer_list sfp_timer; | 463 | struct timer_list service_timer; |
465 | u32 fdir_pballoc; | 464 | u32 fdir_pballoc; |
466 | u32 atr_sample_rate; | 465 | u32 atr_sample_rate; |
467 | spinlock_t fdir_perfect_lock; | 466 | spinlock_t fdir_perfect_lock; |
@@ -492,7 +491,8 @@ enum ixbge_state_t { | |||
492 | __IXGBE_TESTING, | 491 | __IXGBE_TESTING, |
493 | __IXGBE_RESETTING, | 492 | __IXGBE_RESETTING, |
494 | __IXGBE_DOWN, | 493 | __IXGBE_DOWN, |
495 | __IXGBE_SFP_MODULE_NOT_FOUND | 494 | __IXGBE_SERVICE_SCHED, |
495 | __IXGBE_IN_SFP_INIT, | ||
496 | }; | 496 | }; |
497 | 497 | ||
498 | struct ixgbe_rsc_cb { | 498 | struct ixgbe_rsc_cb { |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f8196e0d2745..a5d4226eee0c 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -191,6 +191,22 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) | |||
191 | adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED; | 191 | adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED; |
192 | } | 192 | } |
193 | 193 | ||
194 | static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter) | ||
195 | { | ||
196 | if (!test_bit(__IXGBE_DOWN, &adapter->state) && | ||
197 | !test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state)) | ||
198 | schedule_work(&adapter->service_task); | ||
199 | } | ||
200 | |||
201 | static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter) | ||
202 | { | ||
203 | BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state)); | ||
204 | |||
205 | /* flush memory to make sure state is correct before next watchog */ | ||
206 | smp_mb__before_clear_bit(); | ||
207 | clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state); | ||
208 | } | ||
209 | |||
194 | struct ixgbe_reg_info { | 210 | struct ixgbe_reg_info { |
195 | u32 ofs; | 211 | u32 ofs; |
196 | char *name; | 212 | char *name; |
@@ -1858,15 +1874,19 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr) | |||
1858 | if (eicr & IXGBE_EICR_GPI_SDP2) { | 1874 | if (eicr & IXGBE_EICR_GPI_SDP2) { |
1859 | /* Clear the interrupt */ | 1875 | /* Clear the interrupt */ |
1860 | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2); | 1876 | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2); |
1861 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | 1877 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) { |
1862 | schedule_work(&adapter->sfp_config_module_task); | 1878 | adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; |
1879 | ixgbe_service_event_schedule(adapter); | ||
1880 | } | ||
1863 | } | 1881 | } |
1864 | 1882 | ||
1865 | if (eicr & IXGBE_EICR_GPI_SDP1) { | 1883 | if (eicr & IXGBE_EICR_GPI_SDP1) { |
1866 | /* Clear the interrupt */ | 1884 | /* Clear the interrupt */ |
1867 | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); | 1885 | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); |
1868 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | 1886 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) { |
1869 | schedule_work(&adapter->multispeed_fiber_task); | 1887 | adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; |
1888 | ixgbe_service_event_schedule(adapter); | ||
1889 | } | ||
1870 | } | 1890 | } |
1871 | } | 1891 | } |
1872 | 1892 | ||
@@ -1937,8 +1957,10 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) | |||
1937 | 1957 | ||
1938 | ixgbe_check_fan_failure(adapter, eicr); | 1958 | ixgbe_check_fan_failure(adapter, eicr); |
1939 | 1959 | ||
1960 | /* re-enable the original interrupt state, no lsc, no queues */ | ||
1940 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | 1961 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) |
1941 | IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); | 1962 | IXGBE_WRITE_REG(hw, IXGBE_EIMS, eicr & |
1963 | ~(IXGBE_EIMS_LSC | IXGBE_EIMS_RTX_QUEUE)); | ||
1942 | 1964 | ||
1943 | return IRQ_HANDLED; | 1965 | return IRQ_HANDLED; |
1944 | } | 1966 | } |
@@ -3772,31 +3794,16 @@ static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw) | |||
3772 | **/ | 3794 | **/ |
3773 | static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) | 3795 | static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) |
3774 | { | 3796 | { |
3775 | struct ixgbe_hw *hw = &adapter->hw; | 3797 | /* |
3798 | * We are assuming the worst case scenerio here, and that | ||
3799 | * is that an SFP was inserted/removed after the reset | ||
3800 | * but before SFP detection was enabled. As such the best | ||
3801 | * solution is to just start searching as soon as we start | ||
3802 | */ | ||
3803 | if (adapter->hw.mac.type == ixgbe_mac_82598EB) | ||
3804 | adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; | ||
3776 | 3805 | ||
3777 | if (hw->phy.multispeed_fiber) { | 3806 | adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; |
3778 | /* | ||
3779 | * In multispeed fiber setups, the device may not have | ||
3780 | * had a physical connection when the driver loaded. | ||
3781 | * If that's the case, the initial link configuration | ||
3782 | * couldn't get the MAC into 10G or 1G mode, so we'll | ||
3783 | * never have a link status change interrupt fire. | ||
3784 | * We need to try and force an autonegotiation | ||
3785 | * session, then bring up link. | ||
3786 | */ | ||
3787 | if (hw->mac.ops.setup_sfp) | ||
3788 | hw->mac.ops.setup_sfp(hw); | ||
3789 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) | ||
3790 | schedule_work(&adapter->multispeed_fiber_task); | ||
3791 | } else { | ||
3792 | /* | ||
3793 | * Direct Attach Cu and non-multispeed fiber modules | ||
3794 | * still need to be configured properly prior to | ||
3795 | * attempting link. | ||
3796 | */ | ||
3797 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_MOD_TASK)) | ||
3798 | schedule_work(&adapter->sfp_config_module_task); | ||
3799 | } | ||
3800 | } | 3807 | } |
3801 | 3808 | ||
3802 | /** | 3809 | /** |
@@ -3926,17 +3933,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) | |||
3926 | e_crit(drv, "Fan has stopped, replace the adapter\n"); | 3933 | e_crit(drv, "Fan has stopped, replace the adapter\n"); |
3927 | } | 3934 | } |
3928 | 3935 | ||
3929 | /* | ||
3930 | * For hot-pluggable SFP+ devices, a new SFP+ module may have | ||
3931 | * arrived before interrupts were enabled but after probe. Such | ||
3932 | * devices wouldn't have their type identified yet. We need to | ||
3933 | * kick off the SFP+ module setup first, then try to bring up link. | ||
3934 | * If we're not hot-pluggable SFP+, we just need to configure link | ||
3935 | * and bring it up. | ||
3936 | */ | ||
3937 | if (hw->phy.type == ixgbe_phy_none) | ||
3938 | schedule_work(&adapter->sfp_config_module_task); | ||
3939 | |||
3940 | /* enable transmits */ | 3936 | /* enable transmits */ |
3941 | netif_tx_start_all_queues(adapter->netdev); | 3937 | netif_tx_start_all_queues(adapter->netdev); |
3942 | 3938 | ||
@@ -3945,6 +3941,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) | |||
3945 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; | 3941 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; |
3946 | adapter->link_check_timeout = jiffies; | 3942 | adapter->link_check_timeout = jiffies; |
3947 | mod_timer(&adapter->watchdog_timer, jiffies); | 3943 | mod_timer(&adapter->watchdog_timer, jiffies); |
3944 | mod_timer(&adapter->service_timer, jiffies); | ||
3948 | 3945 | ||
3949 | /* Set PF Reset Done bit so PF/VF Mail Ops can work */ | 3946 | /* Set PF Reset Done bit so PF/VF Mail Ops can work */ |
3950 | ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); | 3947 | ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); |
@@ -3957,6 +3954,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) | |||
3957 | void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) | 3954 | void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) |
3958 | { | 3955 | { |
3959 | WARN_ON(in_interrupt()); | 3956 | WARN_ON(in_interrupt()); |
3957 | /* put off any impending NetWatchDogTimeout */ | ||
3958 | adapter->netdev->trans_start = jiffies; | ||
3959 | |||
3960 | while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) | 3960 | while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) |
3961 | usleep_range(1000, 2000); | 3961 | usleep_range(1000, 2000); |
3962 | ixgbe_down(adapter); | 3962 | ixgbe_down(adapter); |
@@ -3985,10 +3985,20 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) | |||
3985 | struct ixgbe_hw *hw = &adapter->hw; | 3985 | struct ixgbe_hw *hw = &adapter->hw; |
3986 | int err; | 3986 | int err; |
3987 | 3987 | ||
3988 | /* lock SFP init bit to prevent race conditions with the watchdog */ | ||
3989 | while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state)) | ||
3990 | usleep_range(1000, 2000); | ||
3991 | |||
3992 | /* clear all SFP and link config related flags while holding SFP_INIT */ | ||
3993 | adapter->flags2 &= ~(IXGBE_FLAG2_SEARCH_FOR_SFP | | ||
3994 | IXGBE_FLAG2_SFP_NEEDS_RESET); | ||
3995 | adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG; | ||
3996 | |||
3988 | err = hw->mac.ops.init_hw(hw); | 3997 | err = hw->mac.ops.init_hw(hw); |
3989 | switch (err) { | 3998 | switch (err) { |
3990 | case 0: | 3999 | case 0: |
3991 | case IXGBE_ERR_SFP_NOT_PRESENT: | 4000 | case IXGBE_ERR_SFP_NOT_PRESENT: |
4001 | case IXGBE_ERR_SFP_NOT_SUPPORTED: | ||
3992 | break; | 4002 | break; |
3993 | case IXGBE_ERR_MASTER_REQUESTS_PENDING: | 4003 | case IXGBE_ERR_MASTER_REQUESTS_PENDING: |
3994 | e_dev_err("master disable timed out\n"); | 4004 | e_dev_err("master disable timed out\n"); |
@@ -4006,6 +4016,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) | |||
4006 | e_dev_err("Hardware Error: %d\n", err); | 4016 | e_dev_err("Hardware Error: %d\n", err); |
4007 | } | 4017 | } |
4008 | 4018 | ||
4019 | clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state); | ||
4020 | |||
4009 | /* reprogram the RAR[0] in case user changed it. */ | 4021 | /* reprogram the RAR[0] in case user changed it. */ |
4010 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs, | 4022 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs, |
4011 | IXGBE_RAH_AV); | 4023 | IXGBE_RAH_AV); |
@@ -4167,11 +4179,9 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
4167 | 4179 | ||
4168 | netif_tx_stop_all_queues(netdev); | 4180 | netif_tx_stop_all_queues(netdev); |
4169 | 4181 | ||
4170 | clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); | ||
4171 | del_timer_sync(&adapter->sfp_timer); | ||
4172 | del_timer_sync(&adapter->watchdog_timer); | 4182 | del_timer_sync(&adapter->watchdog_timer); |
4173 | cancel_work_sync(&adapter->watchdog_task); | 4183 | cancel_work_sync(&adapter->watchdog_task); |
4174 | 4184 | /* call carrier off first to avoid false dev_watchdog timeouts */ | |
4175 | netif_carrier_off(netdev); | 4185 | netif_carrier_off(netdev); |
4176 | netif_tx_disable(netdev); | 4186 | netif_tx_disable(netdev); |
4177 | 4187 | ||
@@ -4179,6 +4189,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
4179 | 4189 | ||
4180 | ixgbe_napi_disable_all(adapter); | 4190 | ixgbe_napi_disable_all(adapter); |
4181 | 4191 | ||
4192 | adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; | ||
4193 | |||
4194 | del_timer_sync(&adapter->service_timer); | ||
4195 | |||
4182 | /* Cleanup the affinity_hint CPU mask memory and callback */ | 4196 | /* Cleanup the affinity_hint CPU mask memory and callback */ |
4183 | for (i = 0; i < num_q_vectors; i++) { | 4197 | for (i = 0; i < num_q_vectors; i++) { |
4184 | struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; | 4198 | struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; |
@@ -5148,57 +5162,6 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter) | |||
5148 | } | 5162 | } |
5149 | 5163 | ||
5150 | /** | 5164 | /** |
5151 | * ixgbe_sfp_timer - worker thread to find a missing module | ||
5152 | * @data: pointer to our adapter struct | ||
5153 | **/ | ||
5154 | static void ixgbe_sfp_timer(unsigned long data) | ||
5155 | { | ||
5156 | struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; | ||
5157 | |||
5158 | /* | ||
5159 | * Do the sfp_timer outside of interrupt context due to the | ||
5160 | * delays that sfp+ detection requires | ||
5161 | */ | ||
5162 | schedule_work(&adapter->sfp_task); | ||
5163 | } | ||
5164 | |||
5165 | /** | ||
5166 | * ixgbe_sfp_task - worker thread to find a missing module | ||
5167 | * @work: pointer to work_struct containing our data | ||
5168 | **/ | ||
5169 | static void ixgbe_sfp_task(struct work_struct *work) | ||
5170 | { | ||
5171 | struct ixgbe_adapter *adapter = container_of(work, | ||
5172 | struct ixgbe_adapter, | ||
5173 | sfp_task); | ||
5174 | struct ixgbe_hw *hw = &adapter->hw; | ||
5175 | |||
5176 | if ((hw->phy.type == ixgbe_phy_nl) && | ||
5177 | (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) { | ||
5178 | s32 ret = hw->phy.ops.identify_sfp(hw); | ||
5179 | if (ret == IXGBE_ERR_SFP_NOT_PRESENT) | ||
5180 | goto reschedule; | ||
5181 | ret = hw->phy.ops.reset(hw); | ||
5182 | if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { | ||
5183 | e_dev_err("failed to initialize because an unsupported " | ||
5184 | "SFP+ module type was detected.\n"); | ||
5185 | e_dev_err("Reload the driver after installing a " | ||
5186 | "supported module.\n"); | ||
5187 | unregister_netdev(adapter->netdev); | ||
5188 | } else { | ||
5189 | e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type); | ||
5190 | } | ||
5191 | /* don't need this routine any more */ | ||
5192 | clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); | ||
5193 | } | ||
5194 | return; | ||
5195 | reschedule: | ||
5196 | if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state)) | ||
5197 | mod_timer(&adapter->sfp_timer, | ||
5198 | round_jiffies(jiffies + (2 * HZ))); | ||
5199 | } | ||
5200 | |||
5201 | /** | ||
5202 | * ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter) | 5165 | * ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter) |
5203 | * @adapter: board private structure to initialize | 5166 | * @adapter: board private structure to initialize |
5204 | * | 5167 | * |
@@ -6042,65 +6005,6 @@ watchdog_short_circuit: | |||
6042 | } | 6005 | } |
6043 | 6006 | ||
6044 | /** | 6007 | /** |
6045 | * ixgbe_multispeed_fiber_task - worker thread to configure multispeed fiber | ||
6046 | * @work: pointer to work_struct containing our data | ||
6047 | **/ | ||
6048 | static void ixgbe_multispeed_fiber_task(struct work_struct *work) | ||
6049 | { | ||
6050 | struct ixgbe_adapter *adapter = container_of(work, | ||
6051 | struct ixgbe_adapter, | ||
6052 | multispeed_fiber_task); | ||
6053 | struct ixgbe_hw *hw = &adapter->hw; | ||
6054 | u32 autoneg; | ||
6055 | bool negotiation; | ||
6056 | |||
6057 | adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK; | ||
6058 | autoneg = hw->phy.autoneg_advertised; | ||
6059 | if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) | ||
6060 | hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); | ||
6061 | hw->mac.autotry_restart = false; | ||
6062 | if (hw->mac.ops.setup_link) | ||
6063 | hw->mac.ops.setup_link(hw, autoneg, negotiation, true); | ||
6064 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; | ||
6065 | adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK; | ||
6066 | } | ||
6067 | |||
6068 | /** | ||
6069 | * ixgbe_sfp_config_module_task - worker thread to configure a new SFP+ module | ||
6070 | * @work: pointer to work_struct containing our data | ||
6071 | **/ | ||
6072 | static void ixgbe_sfp_config_module_task(struct work_struct *work) | ||
6073 | { | ||
6074 | struct ixgbe_adapter *adapter = container_of(work, | ||
6075 | struct ixgbe_adapter, | ||
6076 | sfp_config_module_task); | ||
6077 | struct ixgbe_hw *hw = &adapter->hw; | ||
6078 | u32 err; | ||
6079 | |||
6080 | adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK; | ||
6081 | |||
6082 | /* Time for electrical oscillations to settle down */ | ||
6083 | msleep(100); | ||
6084 | err = hw->phy.ops.identify_sfp(hw); | ||
6085 | |||
6086 | if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | ||
6087 | e_dev_err("failed to initialize because an unsupported SFP+ " | ||
6088 | "module type was detected.\n"); | ||
6089 | e_dev_err("Reload the driver after installing a supported " | ||
6090 | "module.\n"); | ||
6091 | unregister_netdev(adapter->netdev); | ||
6092 | return; | ||
6093 | } | ||
6094 | if (hw->mac.ops.setup_sfp) | ||
6095 | hw->mac.ops.setup_sfp(hw); | ||
6096 | |||
6097 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) | ||
6098 | /* This will also work for DA Twinax connections */ | ||
6099 | schedule_work(&adapter->multispeed_fiber_task); | ||
6100 | adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK; | ||
6101 | } | ||
6102 | |||
6103 | /** | ||
6104 | * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table | 6008 | * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table |
6105 | * @work: pointer to work_struct containing our data | 6009 | * @work: pointer to work_struct containing our data |
6106 | **/ | 6010 | **/ |
@@ -6273,6 +6177,141 @@ static void ixgbe_watchdog_task(struct work_struct *work) | |||
6273 | mutex_unlock(&ixgbe_watchdog_lock); | 6177 | mutex_unlock(&ixgbe_watchdog_lock); |
6274 | } | 6178 | } |
6275 | 6179 | ||
6180 | /** | ||
6181 | * ixgbe_sfp_detection_subtask - poll for SFP+ cable | ||
6182 | * @adapter - the ixgbe adapter structure | ||
6183 | **/ | ||
6184 | static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter) | ||
6185 | { | ||
6186 | struct ixgbe_hw *hw = &adapter->hw; | ||
6187 | s32 err; | ||
6188 | |||
6189 | /* not searching for SFP so there is nothing to do here */ | ||
6190 | if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) && | ||
6191 | !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET)) | ||
6192 | return; | ||
6193 | |||
6194 | /* someone else is in init, wait until next service event */ | ||
6195 | if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state)) | ||
6196 | return; | ||
6197 | |||
6198 | err = hw->phy.ops.identify_sfp(hw); | ||
6199 | if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) | ||
6200 | goto sfp_out; | ||
6201 | |||
6202 | if (err == IXGBE_ERR_SFP_NOT_PRESENT) { | ||
6203 | /* If no cable is present, then we need to reset | ||
6204 | * the next time we find a good cable. */ | ||
6205 | adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; | ||
6206 | } | ||
6207 | |||
6208 | /* exit on error */ | ||
6209 | if (err) | ||
6210 | goto sfp_out; | ||
6211 | |||
6212 | /* exit if reset not needed */ | ||
6213 | if (!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET)) | ||
6214 | goto sfp_out; | ||
6215 | |||
6216 | adapter->flags2 &= ~IXGBE_FLAG2_SFP_NEEDS_RESET; | ||
6217 | |||
6218 | /* | ||
6219 | * A module may be identified correctly, but the EEPROM may not have | ||
6220 | * support for that module. setup_sfp() will fail in that case, so | ||
6221 | * we should not allow that module to load. | ||
6222 | */ | ||
6223 | if (hw->mac.type == ixgbe_mac_82598EB) | ||
6224 | err = hw->phy.ops.reset(hw); | ||
6225 | else | ||
6226 | err = hw->mac.ops.setup_sfp(hw); | ||
6227 | |||
6228 | if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) | ||
6229 | goto sfp_out; | ||
6230 | |||
6231 | adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; | ||
6232 | e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type); | ||
6233 | |||
6234 | sfp_out: | ||
6235 | clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state); | ||
6236 | |||
6237 | if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) && | ||
6238 | (adapter->netdev->reg_state == NETREG_REGISTERED)) { | ||
6239 | e_dev_err("failed to initialize because an unsupported " | ||
6240 | "SFP+ module type was detected.\n"); | ||
6241 | e_dev_err("Reload the driver after installing a " | ||
6242 | "supported module.\n"); | ||
6243 | unregister_netdev(adapter->netdev); | ||
6244 | } | ||
6245 | } | ||
6246 | |||
6247 | /** | ||
6248 | * ixgbe_sfp_link_config_subtask - set up link SFP after module install | ||
6249 | * @adapter - the ixgbe adapter structure | ||
6250 | **/ | ||
6251 | static void ixgbe_sfp_link_config_subtask(struct ixgbe_adapter *adapter) | ||
6252 | { | ||
6253 | struct ixgbe_hw *hw = &adapter->hw; | ||
6254 | u32 autoneg; | ||
6255 | bool negotiation; | ||
6256 | |||
6257 | if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_CONFIG)) | ||
6258 | return; | ||
6259 | |||
6260 | /* someone else is in init, wait until next service event */ | ||
6261 | if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state)) | ||
6262 | return; | ||
6263 | |||
6264 | adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG; | ||
6265 | |||
6266 | autoneg = hw->phy.autoneg_advertised; | ||
6267 | if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) | ||
6268 | hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); | ||
6269 | hw->mac.autotry_restart = false; | ||
6270 | if (hw->mac.ops.setup_link) | ||
6271 | hw->mac.ops.setup_link(hw, autoneg, negotiation, true); | ||
6272 | |||
6273 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; | ||
6274 | adapter->link_check_timeout = jiffies; | ||
6275 | clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state); | ||
6276 | } | ||
6277 | |||
6278 | /** | ||
6279 | * ixgbe_service_timer - Timer Call-back | ||
6280 | * @data: pointer to adapter cast into an unsigned long | ||
6281 | **/ | ||
6282 | static void ixgbe_service_timer(unsigned long data) | ||
6283 | { | ||
6284 | struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; | ||
6285 | unsigned long next_event_offset; | ||
6286 | |||
6287 | /* poll faster when waiting for link */ | ||
6288 | if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) | ||
6289 | next_event_offset = HZ / 10; | ||
6290 | else | ||
6291 | next_event_offset = HZ * 2; | ||
6292 | |||
6293 | /* Reset the timer */ | ||
6294 | mod_timer(&adapter->service_timer, next_event_offset + jiffies); | ||
6295 | |||
6296 | ixgbe_service_event_schedule(adapter); | ||
6297 | } | ||
6298 | |||
6299 | /** | ||
6300 | * ixgbe_service_task - manages and runs subtasks | ||
6301 | * @work: pointer to work_struct containing our data | ||
6302 | **/ | ||
6303 | static void ixgbe_service_task(struct work_struct *work) | ||
6304 | { | ||
6305 | struct ixgbe_adapter *adapter = container_of(work, | ||
6306 | struct ixgbe_adapter, | ||
6307 | service_task); | ||
6308 | |||
6309 | ixgbe_sfp_detection_subtask(adapter); | ||
6310 | ixgbe_sfp_link_config_subtask(adapter); | ||
6311 | |||
6312 | ixgbe_service_event_complete(adapter); | ||
6313 | } | ||
6314 | |||
6276 | static int ixgbe_tso(struct ixgbe_adapter *adapter, | 6315 | static int ixgbe_tso(struct ixgbe_adapter *adapter, |
6277 | struct ixgbe_ring *tx_ring, struct sk_buff *skb, | 6316 | struct ixgbe_ring *tx_ring, struct sk_buff *skb, |
6278 | u32 tx_flags, u8 *hdr_len, __be16 protocol) | 6317 | u32 tx_flags, u8 *hdr_len, __be16 protocol) |
@@ -7317,22 +7356,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
7317 | hw->phy.mdio.mdio_read = ixgbe_mdio_read; | 7356 | hw->phy.mdio.mdio_read = ixgbe_mdio_read; |
7318 | hw->phy.mdio.mdio_write = ixgbe_mdio_write; | 7357 | hw->phy.mdio.mdio_write = ixgbe_mdio_write; |
7319 | 7358 | ||
7320 | /* set up this timer and work struct before calling get_invariants | ||
7321 | * which might start the timer | ||
7322 | */ | ||
7323 | init_timer(&adapter->sfp_timer); | ||
7324 | adapter->sfp_timer.function = ixgbe_sfp_timer; | ||
7325 | adapter->sfp_timer.data = (unsigned long) adapter; | ||
7326 | |||
7327 | INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task); | ||
7328 | |||
7329 | /* multispeed fiber has its own tasklet, called from GPI SDP1 context */ | ||
7330 | INIT_WORK(&adapter->multispeed_fiber_task, ixgbe_multispeed_fiber_task); | ||
7331 | |||
7332 | /* a new SFP+ module arrival, called from GPI SDP2 context */ | ||
7333 | INIT_WORK(&adapter->sfp_config_module_task, | ||
7334 | ixgbe_sfp_config_module_task); | ||
7335 | |||
7336 | ii->get_invariants(hw); | 7359 | ii->get_invariants(hw); |
7337 | 7360 | ||
7338 | /* setup the private structure */ | 7361 | /* setup the private structure */ |
@@ -7366,17 +7389,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
7366 | hw->phy.reset_if_overtemp = false; | 7389 | hw->phy.reset_if_overtemp = false; |
7367 | if (err == IXGBE_ERR_SFP_NOT_PRESENT && | 7390 | if (err == IXGBE_ERR_SFP_NOT_PRESENT && |
7368 | hw->mac.type == ixgbe_mac_82598EB) { | 7391 | hw->mac.type == ixgbe_mac_82598EB) { |
7369 | /* | ||
7370 | * Start a kernel thread to watch for a module to arrive. | ||
7371 | * Only do this for 82598, since 82599 will generate | ||
7372 | * interrupts on module arrival. | ||
7373 | */ | ||
7374 | set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); | ||
7375 | mod_timer(&adapter->sfp_timer, | ||
7376 | round_jiffies(jiffies + (2 * HZ))); | ||
7377 | err = 0; | 7392 | err = 0; |
7378 | } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | 7393 | } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { |
7379 | e_dev_err("failed to initialize because an unsupported SFP+ " | 7394 | e_dev_err("failed to load because an unsupported SFP+ " |
7380 | "module type was detected.\n"); | 7395 | "module type was detected.\n"); |
7381 | e_dev_err("Reload the driver after installing a supported " | 7396 | e_dev_err("Reload the driver after installing a supported " |
7382 | "module.\n"); | 7397 | "module.\n"); |
@@ -7468,6 +7483,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
7468 | (hw->mac.type == ixgbe_mac_82599EB)))) | 7483 | (hw->mac.type == ixgbe_mac_82599EB)))) |
7469 | hw->mac.ops.disable_tx_laser(hw); | 7484 | hw->mac.ops.disable_tx_laser(hw); |
7470 | 7485 | ||
7486 | setup_timer(&adapter->service_timer, &ixgbe_service_timer, | ||
7487 | (unsigned long) adapter); | ||
7471 | init_timer(&adapter->watchdog_timer); | 7488 | init_timer(&adapter->watchdog_timer); |
7472 | adapter->watchdog_timer.function = ixgbe_watchdog; | 7489 | adapter->watchdog_timer.function = ixgbe_watchdog; |
7473 | adapter->watchdog_timer.data = (unsigned long)adapter; | 7490 | adapter->watchdog_timer.data = (unsigned long)adapter; |
@@ -7475,6 +7492,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
7475 | INIT_WORK(&adapter->reset_task, ixgbe_reset_task); | 7492 | INIT_WORK(&adapter->reset_task, ixgbe_reset_task); |
7476 | INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task); | 7493 | INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task); |
7477 | 7494 | ||
7495 | INIT_WORK(&adapter->service_task, ixgbe_service_task); | ||
7496 | clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state); | ||
7497 | |||
7478 | err = ixgbe_init_interrupt_scheme(adapter); | 7498 | err = ixgbe_init_interrupt_scheme(adapter); |
7479 | if (err) | 7499 | if (err) |
7480 | goto err_sw_init; | 7500 | goto err_sw_init; |
@@ -7593,11 +7613,7 @@ err_sw_init: | |||
7593 | err_eeprom: | 7613 | err_eeprom: |
7594 | if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) | 7614 | if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) |
7595 | ixgbe_disable_sriov(adapter); | 7615 | ixgbe_disable_sriov(adapter); |
7596 | clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); | 7616 | adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP; |
7597 | del_timer_sync(&adapter->sfp_timer); | ||
7598 | cancel_work_sync(&adapter->sfp_task); | ||
7599 | cancel_work_sync(&adapter->multispeed_fiber_task); | ||
7600 | cancel_work_sync(&adapter->sfp_config_module_task); | ||
7601 | iounmap(hw->hw_addr); | 7617 | iounmap(hw->hw_addr); |
7602 | err_ioremap: | 7618 | err_ioremap: |
7603 | free_netdev(netdev); | 7619 | free_netdev(netdev); |
@@ -7625,19 +7641,15 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) | |||
7625 | struct net_device *netdev = adapter->netdev; | 7641 | struct net_device *netdev = adapter->netdev; |
7626 | 7642 | ||
7627 | set_bit(__IXGBE_DOWN, &adapter->state); | 7643 | set_bit(__IXGBE_DOWN, &adapter->state); |
7644 | cancel_work_sync(&adapter->service_task); | ||
7628 | 7645 | ||
7629 | /* | 7646 | /* |
7630 | * The timers may be rescheduled, so explicitly disable them | 7647 | * The timers may be rescheduled, so explicitly disable them |
7631 | * from being rescheduled. | 7648 | * from being rescheduled. |
7632 | */ | 7649 | */ |
7633 | clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); | ||
7634 | del_timer_sync(&adapter->watchdog_timer); | 7650 | del_timer_sync(&adapter->watchdog_timer); |
7635 | del_timer_sync(&adapter->sfp_timer); | ||
7636 | 7651 | ||
7637 | cancel_work_sync(&adapter->watchdog_task); | 7652 | cancel_work_sync(&adapter->watchdog_task); |
7638 | cancel_work_sync(&adapter->sfp_task); | ||
7639 | cancel_work_sync(&adapter->multispeed_fiber_task); | ||
7640 | cancel_work_sync(&adapter->sfp_config_module_task); | ||
7641 | if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || | 7653 | if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || |
7642 | adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) | 7654 | adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) |
7643 | cancel_work_sync(&adapter->fdir_reinit_task); | 7655 | cancel_work_sync(&adapter->fdir_reinit_task); |