ixgbe: cleanup checksum to allow error results
Currently the shared code checksum calculation function only returns a u16 and cannot return an error code. Unfortunately a variety of errors can happen that completely prevent the calculation of a checksum. So, change the function return value from a u16 to an s32 and return a negative value on error, or the positive checksum value when there is no error. Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
committed by
Jeff Kirsher
parent
28abba05d9
commit
735c35afed
@@ -1625,7 +1625,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
|
|||||||
* ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
|
* ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
**/
|
**/
|
||||||
u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
|
s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
u16 i;
|
u16 i;
|
||||||
u16 j;
|
u16 j;
|
||||||
@@ -1636,7 +1636,7 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
|
|||||||
|
|
||||||
/* Include 0x0-0x3F in the checksum */
|
/* Include 0x0-0x3F in the checksum */
|
||||||
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
|
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
|
||||||
if (hw->eeprom.ops.read(hw, i, &word) != 0) {
|
if (hw->eeprom.ops.read(hw, i, &word)) {
|
||||||
hw_dbg(hw, "EEPROM read failed\n");
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1645,24 +1645,35 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
|
|||||||
|
|
||||||
/* Include all data from pointers except for the fw pointer */
|
/* Include all data from pointers except for the fw pointer */
|
||||||
for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
|
for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
|
||||||
hw->eeprom.ops.read(hw, i, &pointer);
|
if (hw->eeprom.ops.read(hw, i, &pointer)) {
|
||||||
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
|
return IXGBE_ERR_EEPROM;
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure the pointer seems valid */
|
/* If the pointer seems invalid */
|
||||||
if (pointer != 0xFFFF && pointer != 0) {
|
if (pointer == 0xFFFF || pointer == 0)
|
||||||
hw->eeprom.ops.read(hw, pointer, &length);
|
continue;
|
||||||
|
|
||||||
if (length != 0xFFFF && length != 0) {
|
if (hw->eeprom.ops.read(hw, pointer, &length)) {
|
||||||
for (j = pointer+1; j <= pointer+length; j++) {
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
hw->eeprom.ops.read(hw, j, &word);
|
return IXGBE_ERR_EEPROM;
|
||||||
checksum += word;
|
}
|
||||||
}
|
|
||||||
|
if (length == 0xFFFF || length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (j = pointer + 1; j <= pointer + length; j++) {
|
||||||
|
if (hw->eeprom.ops.read(hw, j, &word)) {
|
||||||
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
|
return IXGBE_ERR_EEPROM;
|
||||||
}
|
}
|
||||||
|
checksum += word;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checksum = (u16)IXGBE_EEPROM_SUM - checksum;
|
checksum = (u16)IXGBE_EEPROM_SUM - checksum;
|
||||||
|
|
||||||
return checksum;
|
return (s32)checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1686,26 +1697,33 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
|
|||||||
* 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) {
|
|
||||||
checksum = hw->eeprom.ops.calc_checksum(hw);
|
|
||||||
|
|
||||||
hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 (checksum_val)
|
|
||||||
*checksum_val = checksum;
|
|
||||||
} else {
|
|
||||||
hw_dbg(hw, "EEPROM read failed\n");
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = hw->eeprom.ops.calc_checksum(hw);
|
||||||
|
if (status < 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
checksum = (u16)(status & 0xffff);
|
||||||
|
|
||||||
|
status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
|
||||||
|
if (status) {
|
||||||
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 (checksum_val)
|
||||||
|
*checksum_val = checksum;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1724,15 +1742,19 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
|
|||||||
* 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) {
|
|
||||||
checksum = hw->eeprom.ops.calc_checksum(hw);
|
|
||||||
status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
|
|
||||||
checksum);
|
|
||||||
} else {
|
|
||||||
hw_dbg(hw, "EEPROM read failed\n");
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = hw->eeprom.ops.calc_checksum(hw);
|
||||||
|
if (status < 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
checksum = (u16)(status & 0xffff);
|
||||||
|
|
||||||
|
status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
|||||||
u16 *data);
|
u16 *data);
|
||||||
s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
u16 words, u16 *data);
|
u16 words, u16 *data);
|
||||||
u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
|
s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
|
||||||
s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
|
s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
|
||||||
u16 *checksum_val);
|
u16 *checksum_val);
|
||||||
s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
|
s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
|
||||||
|
|||||||
@@ -2871,7 +2871,7 @@ struct ixgbe_eeprom_operations {
|
|||||||
s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
|
s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
|
||||||
s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
|
s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
|
||||||
s32 (*update_checksum)(struct ixgbe_hw *);
|
s32 (*update_checksum)(struct ixgbe_hw *);
|
||||||
u16 (*calc_checksum)(struct ixgbe_hw *);
|
s32 (*calc_checksum)(struct ixgbe_hw *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ixgbe_mac_operations {
|
struct ixgbe_mac_operations {
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
|
|||||||
*
|
*
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
**/
|
**/
|
||||||
static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
|
static s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
u16 i;
|
u16 i;
|
||||||
u16 j;
|
u16 j;
|
||||||
@@ -324,6 +324,8 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
|
|||||||
u16 length = 0;
|
u16 length = 0;
|
||||||
u16 pointer = 0;
|
u16 pointer = 0;
|
||||||
u16 word = 0;
|
u16 word = 0;
|
||||||
|
u16 checksum_last_word = IXGBE_EEPROM_CHECKSUM;
|
||||||
|
u16 ptr_start = IXGBE_PCIE_ANALOG_PTR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
@@ -332,10 +334,10 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Include 0x0-0x3F in the checksum */
|
/* Include 0x0-0x3F in the checksum */
|
||||||
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
|
for (i = 0; i < checksum_last_word; i++) {
|
||||||
if (ixgbe_read_eerd_generic(hw, i, &word) != 0) {
|
if (ixgbe_read_eerd_generic(hw, i, &word)) {
|
||||||
hw_dbg(hw, "EEPROM read failed\n");
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
break;
|
return IXGBE_ERR_EEPROM;
|
||||||
}
|
}
|
||||||
checksum += word;
|
checksum += word;
|
||||||
}
|
}
|
||||||
@@ -344,11 +346,11 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
|
|||||||
* Include all data from pointers 0x3, 0x6-0xE. This excludes the
|
* Include all data from pointers 0x3, 0x6-0xE. This excludes the
|
||||||
* FW, PHY module, and PCIe Expansion/Option ROM pointers.
|
* FW, PHY module, and PCIe Expansion/Option ROM pointers.
|
||||||
*/
|
*/
|
||||||
for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
|
for (i = ptr_start; i < IXGBE_FW_PTR; i++) {
|
||||||
if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
|
if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ixgbe_read_eerd_generic(hw, i, &pointer) != 0) {
|
if (ixgbe_read_eerd_generic(hw, i, &pointer)) {
|
||||||
hw_dbg(hw, "EEPROM read failed\n");
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -358,8 +360,9 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
|
|||||||
pointer >= hw->eeprom.word_size)
|
pointer >= hw->eeprom.word_size)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ixgbe_read_eerd_generic(hw, pointer, &length) != 0) {
|
if (ixgbe_read_eerd_generic(hw, pointer, &length)) {
|
||||||
hw_dbg(hw, "EEPROM read failed\n");
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
|
return IXGBE_ERR_EEPROM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,10 +371,10 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
|
|||||||
(pointer + length) >= hw->eeprom.word_size)
|
(pointer + length) >= hw->eeprom.word_size)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j = pointer+1; j <= pointer+length; j++) {
|
for (j = pointer + 1; j <= pointer + length; j++) {
|
||||||
if (ixgbe_read_eerd_generic(hw, j, &word) != 0) {
|
if (ixgbe_read_eerd_generic(hw, j, &word)) {
|
||||||
hw_dbg(hw, "EEPROM read failed\n");
|
hw_dbg(hw, "EEPROM read failed\n");
|
||||||
break;
|
return IXGBE_ERR_EEPROM;
|
||||||
}
|
}
|
||||||
checksum += word;
|
checksum += word;
|
||||||
}
|
}
|
||||||
@@ -379,7 +382,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
|
|||||||
|
|
||||||
checksum = (u16)IXGBE_EEPROM_SUM - checksum;
|
checksum = (u16)IXGBE_EEPROM_SUM - checksum;
|
||||||
|
|
||||||
return checksum;
|
return (s32)checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -410,23 +413,34 @@ static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
|
|||||||
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
|
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
|
||||||
return IXGBE_ERR_SWFW_SYNC;
|
return IXGBE_ERR_SWFW_SYNC;
|
||||||
|
|
||||||
checksum = hw->eeprom.ops.calc_checksum(hw);
|
status = hw->eeprom.ops.calc_checksum(hw);
|
||||||
|
if (status < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
checksum = (u16)(status & 0xffff);
|
||||||
|
|
||||||
/* 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.
|
||||||
*/
|
*/
|
||||||
status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
|
status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
|
||||||
&read_checksum);
|
&read_checksum);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
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) {
|
||||||
|
hw_dbg(hw, "Invalid EEPROM 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;
|
||||||
|
|
||||||
/* Verify read and calculated checksums are the same */
|
out:
|
||||||
if (read_checksum != checksum)
|
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
|
||||||
return IXGBE_ERR_EEPROM_CHECKSUM;
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -457,15 +471,22 @@ static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
|
|||||||
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
|
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
|
||||||
return IXGBE_ERR_SWFW_SYNC;
|
return IXGBE_ERR_SWFW_SYNC;
|
||||||
|
|
||||||
checksum = hw->eeprom.ops.calc_checksum(hw);
|
status = hw->eeprom.ops.calc_checksum(hw);
|
||||||
|
if (status < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
checksum = (u16)(status & 0xffff);
|
||||||
|
|
||||||
/* 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, checksum);
|
status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
|
||||||
if (!status)
|
if (status)
|
||||||
status = ixgbe_update_flash_X540(hw);
|
goto out;
|
||||||
|
|
||||||
|
status = ixgbe_update_flash_X540(hw);
|
||||||
|
|
||||||
|
out:
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user