Commit e4856696 authored by Mark Rustad's avatar Mark Rustad Committed by Jeff Kirsher

ixgbe: Fix spurious release of semaphore in EEPROM access

Failure to acquire the semaphore would lead to a spurious release
of the semaphore in several functions. Do not release a semaphore
that you did not get.
Signed-off-by: default avatarMark Rustad <mark.d.rustad@intel.com>
Tested-by: default avatarPhil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent d819fc52
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2013 Intel Corporation. Copyright(c) 1999 - 2014 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -258,13 +258,12 @@ static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) ...@@ -258,13 +258,12 @@ static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
**/ **/
static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
{ {
s32 status = 0; s32 status;
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
return IXGBE_ERR_SWFW_SYNC;
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
0)
status = ixgbe_read_eerd_generic(hw, offset, data); status = ixgbe_read_eerd_generic(hw, offset, data);
else
status = IXGBE_ERR_SWFW_SYNC;
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status; return status;
...@@ -282,14 +281,12 @@ static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) ...@@ -282,14 +281,12 @@ static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
u16 offset, u16 words, u16 *data) u16 offset, u16 words, u16 *data)
{ {
s32 status = 0; s32 status;
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
0) return IXGBE_ERR_SWFW_SYNC;
status = ixgbe_read_eerd_buffer_generic(hw, offset,
words, data); status = ixgbe_read_eerd_buffer_generic(hw, offset, words, data);
else
status = IXGBE_ERR_SWFW_SYNC;
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status; return status;
...@@ -305,12 +302,12 @@ static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, ...@@ -305,12 +302,12 @@ static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
**/ **/
static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
{ {
s32 status = 0; s32 status;
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
return IXGBE_ERR_SWFW_SYNC;
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0)
status = ixgbe_write_eewr_generic(hw, offset, data); status = ixgbe_write_eewr_generic(hw, offset, data);
else
status = IXGBE_ERR_SWFW_SYNC;
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status; return status;
...@@ -328,14 +325,12 @@ static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) ...@@ -328,14 +325,12 @@ static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
u16 offset, u16 words, u16 *data) u16 offset, u16 words, u16 *data)
{ {
s32 status = 0; s32 status;
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
0) return IXGBE_ERR_SWFW_SYNC;
status = ixgbe_write_eewr_buffer_generic(hw, offset,
words, data); status = ixgbe_write_eewr_buffer_generic(hw, offset, words, data);
else
status = IXGBE_ERR_SWFW_SYNC;
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status; return status;
...@@ -430,44 +425,37 @@ static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, ...@@ -430,44 +425,37 @@ static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
u16 checksum; u16 checksum;
u16 read_checksum = 0; u16 read_checksum = 0;
/* /* Read the first word from the EEPROM. If this times out or fails, do
* Read the first word from the EEPROM. If this times out or fails, do
* not continue or we could be in for a very long wait while every * not continue or we could be in for a very long wait while every
* EEPROM read fails * EEPROM read fails
*/ */
status = hw->eeprom.ops.read(hw, 0, &checksum); status = hw->eeprom.ops.read(hw, 0, &checksum);
if (status) {
if (status != 0) {
hw_dbg(hw, "EEPROM read failed\n"); hw_dbg(hw, "EEPROM read failed\n");
goto out; return status;
} }
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) { if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
return IXGBE_ERR_SWFW_SYNC;
checksum = hw->eeprom.ops.calc_checksum(hw); checksum = hw->eeprom.ops.calc_checksum(hw);
/* /* Do not use hw->eeprom.ops.read because we do not want to take
* Do not use hw->eeprom.ops.read because we do not want to take
* the synchronization semaphores twice here. * the synchronization semaphores twice here.
*/ */
ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
&read_checksum); &read_checksum);
/* hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
* Verify read checksum from EEPROM is the same as
* calculated checksum
*/
if (read_checksum != checksum)
status = IXGBE_ERR_EEPROM_CHECKSUM;
/* If the user cares, return the calculated checksum */ /* If the user cares, return the calculated checksum */
if (checksum_val) if (checksum_val)
*checksum_val = checksum; *checksum_val = checksum;
} else {
status = IXGBE_ERR_SWFW_SYNC;
}
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); /* Verify read and calculated checksums are the same */
out: if (read_checksum != checksum)
return IXGBE_ERR_EEPROM_CHECKSUM;
return status; return status;
} }
...@@ -484,34 +472,29 @@ static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) ...@@ -484,34 +472,29 @@ static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
s32 status; s32 status;
u16 checksum; u16 checksum;
/* /* Read the first word from the EEPROM. If this times out or fails, do
* Read the first word from the EEPROM. If this times out or fails, do
* not continue or we could be in for a very long wait while every * not continue or we could be in for a very long wait while every
* EEPROM read fails * EEPROM read fails
*/ */
status = hw->eeprom.ops.read(hw, 0, &checksum); status = hw->eeprom.ops.read(hw, 0, &checksum);
if (status) {
if (status != 0)
hw_dbg(hw, "EEPROM read failed\n"); hw_dbg(hw, "EEPROM read failed\n");
return status;
}
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
return IXGBE_ERR_SWFW_SYNC;
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
checksum = hw->eeprom.ops.calc_checksum(hw); checksum = hw->eeprom.ops.calc_checksum(hw);
/* /* Do not use hw->eeprom.ops.write because we do not want to
* Do not use hw->eeprom.ops.write because we do not want to
* take the synchronization semaphores twice here. * take the synchronization semaphores twice here.
*/ */
status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
checksum); if (!status)
if (status == 0)
status = ixgbe_update_flash_X540(hw); status = ixgbe_update_flash_X540(hw);
else
status = IXGBE_ERR_SWFW_SYNC;
}
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status; return status;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment