ixgbe: Place SWFW semaphore in known valid state at probe
authorDon Skidmore <donald.c.skidmore@intel.com>
Wed, 9 Mar 2016 21:45:00 +0000 (16:45 -0500)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Tue, 5 Apr 2016 00:44:50 +0000 (17:44 -0700)
It is possible on some HW that a system reset could occur when we are
holding the SWFW semaphore lock.  So next time the driver was loaded we
would see it incorrectly as locked. This patch will recover from that state
by: Attempting to acquire the semaphore and then regardless of whether or
not it was acquire we immediately release it. This will force us into
a known good state.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
drivers/net/ethernet/intel/ixgbe/ixgbe_x540.h
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c

index f47eb12a9c50332ff00afc0791e7518f8756d8c8..6ecd598c6ef59928556e7dfb6b7179c11570d277 100644 (file)
@@ -1196,6 +1196,7 @@ static const struct ixgbe_mac_operations mac_ops_82598 = {
        .set_fw_drv_ver         = NULL,
        .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync,
        .release_swfw_sync      = &ixgbe_release_swfw_sync,
+       .init_swfw_sync         = NULL,
        .get_thermal_sensor_data = NULL,
        .init_thermal_sensor_thresh = NULL,
        .prot_autoc_read        = &prot_autoc_read_generic,
index c3ae5a701d4307b91f5f942624cc60e0ea5e169e..4bb6b685263be15514a1d78124d5630c0cb1bdd1 100644 (file)
@@ -2228,6 +2228,7 @@ static const struct ixgbe_mac_operations mac_ops_82599 = {
        .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing,
        .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync,
        .release_swfw_sync      = &ixgbe_release_swfw_sync,
+       .init_swfw_sync         = NULL,
        .get_thermal_sensor_data = &ixgbe_get_thermal_sensor_data_generic,
        .init_thermal_sensor_thresh = &ixgbe_init_thermal_sensor_thresh_generic,
        .prot_autoc_read        = &prot_autoc_read_82599,
index 115656c690bfc9f0f20d9a1b8ca644a1e27b3fd0..77c1c85a957cb37b0245fa1cf9caac2769eb3e3c 100644 (file)
@@ -9126,6 +9126,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (err)
                goto err_sw_init;
 
+       /* Make sure the SWFW semaphore is in a valid state */
+       if (hw->mac.ops.init_swfw_sync)
+               hw->mac.ops.init_swfw_sync(hw);
+
        /* Make it possible the adapter to be woken up via WOL */
        switch (adapter->hw.mac.type) {
        case ixgbe_mac_82599EB:
index 787d2b21465e8e28ccb267c6e48a6ef099cad849..bc012ab48475f15270eb63aa613e401b5228749e 100644 (file)
@@ -3266,6 +3266,7 @@ struct ixgbe_mac_operations {
        s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
        s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u32);
        void (*release_swfw_sync)(struct ixgbe_hw *, u32);
+       void (*init_swfw_sync)(struct ixgbe_hw *);
        s32 (*prot_autoc_read)(struct ixgbe_hw *, bool *, u32 *);
        s32 (*prot_autoc_write)(struct ixgbe_hw *, u32, bool);
 
index c00b67b4c1dcd22fcedda4061344068041024d6e..40824d85d807f3bcf3a181226aa01465a6c2ab6c 100644 (file)
@@ -746,6 +746,25 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
        IXGBE_WRITE_FLUSH(hw);
 }
 
+/**
+ *  ixgbe_init_swfw_sync_X540 - Release hardware semaphore
+ *  @hw: pointer to hardware structure
+ *
+ *  This function reset hardware semaphore bits for a semaphore that may
+ *  have be left locked due to a catastrophic failure.
+ **/
+void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw)
+{
+       /* First try to grab the semaphore but we don't need to bother
+        * looking to see whether we got the lock or not since we do
+        * the same thing regardless of whether we got the lock or not.
+        * We got the lock - we release it.
+        * We timeout trying to get the lock - we force its release.
+        */
+       ixgbe_get_swfw_sync_semaphore(hw);
+       ixgbe_release_swfw_sync_semaphore(hw);
+}
+
 /**
  * ixgbe_blink_led_start_X540 - Blink LED based on index.
  * @hw: pointer to hardware structure
@@ -854,6 +873,7 @@ static const struct ixgbe_mac_operations mac_ops_X540 = {
        .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing,
        .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X540,
        .release_swfw_sync      = &ixgbe_release_swfw_sync_X540,
+       .init_swfw_sync         = &ixgbe_init_swfw_sync_X540,
        .disable_rx_buff        = &ixgbe_disable_rx_buff_generic,
        .enable_rx_buff         = &ixgbe_enable_rx_buff_generic,
        .get_thermal_sensor_data = NULL,
index a1468b1f4d8af0c4d10b9fb609f2790262e99f66..e21cd48491d338fc467182cdbf33c8b8b35509fb 100644 (file)
@@ -36,4 +36,5 @@ s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index);
 s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index);
 s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask);
 void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask);
+void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw);
 s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw);
index 972c9aa175032fcc25a1a0903a89813bbd792269..9d3f765638cc67da6b5206013c0e267446d0b57f 100644 (file)
@@ -2432,6 +2432,7 @@ static const struct ixgbe_mac_operations mac_ops_X550 = {
        .setup_sfp              = NULL,
        .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X540,
        .release_swfw_sync      = &ixgbe_release_swfw_sync_X540,
+       .init_swfw_sync         = &ixgbe_init_swfw_sync_X540,
        .prot_autoc_read        = prot_autoc_read_generic,
        .prot_autoc_write       = prot_autoc_write_generic,
        .setup_fc               = ixgbe_setup_fc_generic,
@@ -2449,6 +2450,7 @@ static const struct ixgbe_mac_operations mac_ops_X550EM_x = {
        .setup_sfp              = ixgbe_setup_sfp_modules_X550em,
        .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X550em,
        .release_swfw_sync      = &ixgbe_release_swfw_sync_X550em,
+       .init_swfw_sync         = &ixgbe_init_swfw_sync_X540,
        .setup_fc               = NULL, /* defined later */
 };