ixgbe: Place SWFW semaphore in known valid state at probe
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>
This commit is contained in:
parent
c04f90e592
commit
dbd15b8f9c
7 changed files with 30 additions and 0 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue