From: Maciej Paczkowski <maciej.paczkowski@intel.com>
Date: Thu, 28 Feb 2019 09:52:50 -0800
Subject: i40e: ShadowRAM checksum calculation change
Patch-mainline: v5.2-rc1
Git-commit: 226436dc8ae8539a25a85be8c0e154a28722c3f6
References: jsc#SLE-4797
Due to changes in FW the SW is required to perform double SR dump in
some cases.
Implementation adds two new steps to update nvm checksum function:
* recalculate checksum and check if checksum in NVM is correct
* if checksum in NVM is not correct then update it again
Signed-off-by: Maciej Paczkowski <maciej.paczkowski@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
drivers/net/ethernet/intel/i40e/i40e_nvm.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -597,13 +597,34 @@ i40e_calc_nvm_checksum_exit:
i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw)
{
i40e_status ret_code;
- u16 checksum;
+ u16 checksum, checksum_sr;
__le16 le_sum;
ret_code = i40e_calc_nvm_checksum(hw, &checksum);
- if (!ret_code) {
- le_sum = cpu_to_le16(checksum);
- ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
+ if (ret_code)
+ return ret_code;
+
+ le_sum = cpu_to_le16(checksum);
+ ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
+ 1, &le_sum, true);
+ if (ret_code)
+ return ret_code;
+
+ /* Due to changes in FW the SW is required to perform double SR-dump
+ * in some cases. SR-dump is the process when internal shadow RAM is
+ * dumped into flash bank. It is triggered by setting "last_command"
+ * argument in i40e_write_nvm_aq function call.
+ * Since FW 1.8 we need to calculate SR checksum again and update it
+ * in flash if it is not equal to previously computed checksum.
+ * This situation would occur only in FW >= 1.8
+ */
+ ret_code = i40e_calc_nvm_checksum(hw, &checksum_sr);
+ if (ret_code)
+ return ret_code;
+ if (checksum_sr != checksum) {
+ le_sum = cpu_to_le16(checksum_sr);
+ ret_code = i40e_write_nvm_aq(hw, 0x00,
+ I40E_SR_SW_CHECKSUM_WORD,
1, &le_sum, true);
}