The data buffer for i40e_calc_nvm_checksum() is too big, so move
it off and allocate separately. In addition, use
i40e_read_nvm_buffer() to get the whole shadow RAM, together with
minor enhancements.

Signed-off-by: Helin Zhang <helin.zhang at intel.com>
---
 lib/librte_pmd_i40e/i40e/i40e_nvm.c | 49 +++++++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/lib/librte_pmd_i40e/i40e/i40e_nvm.c 
b/lib/librte_pmd_i40e/i40e/i40e_nvm.c
index 159989b..55d0bed 100644
--- a/lib/librte_pmd_i40e/i40e/i40e_nvm.c
+++ b/lib/librte_pmd_i40e/i40e/i40e_nvm.c
@@ -542,14 +542,21 @@ enum i40e_status_code i40e_write_nvm_buffer(struct 
i40e_hw *hw,
 enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
 {
        enum i40e_status_code ret_code = I40E_SUCCESS;
+       struct i40e_virt_mem vmem;
        u16 pcie_alt_module = 0;
        u16 checksum_local = 0;
        u16 vpd_module = 0;
-       u16 word = 0;
-       u32 i = 0;
+       u16 *data;
+       u16 i = 0;

        DEBUGFUNC("i40e_calc_nvm_checksum");

+       ret_code = i40e_allocate_virt_mem(hw, &vmem,
+                                   I40E_SR_SECTOR_SIZE_IN_WORDS * sizeof(u16));
+       if (ret_code)
+               goto i40e_calc_nvm_checksum_exit;
+       data = (u16 *)vmem.va;
+
        /* read pointer to VPD area */
        ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
        if (ret_code != I40E_SUCCESS) {
@@ -559,7 +566,7 @@ enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw 
*hw, u16 *checksum)

        /* read pointer to PCIe Alt Auto-load module */
        ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
-                                      &pcie_alt_module);
+                                     &pcie_alt_module);
        if (ret_code != I40E_SUCCESS) {
                ret_code = I40E_ERR_NVM_CHECKSUM;
                goto i40e_calc_nvm_checksum_exit;
@@ -569,33 +576,39 @@ enum i40e_status_code i40e_calc_nvm_checksum(struct 
i40e_hw *hw, u16 *checksum)
         * except the VPD and PCIe ALT Auto-load modules
         */
        for (i = 0; i < hw->nvm.sr_size; i++) {
+               /* Read SR page */
+               if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
+                       u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
+                       ret_code = i40e_read_nvm_buffer(hw, i, &words, data);
+                       if (ret_code != I40E_SUCCESS) {
+                               ret_code = I40E_ERR_NVM_CHECKSUM;
+                               goto i40e_calc_nvm_checksum_exit;
+                       }
+               }
+
                /* Skip Checksum word */
                if (i == I40E_SR_SW_CHECKSUM_WORD)
-                       i++;
+                       continue;
                /* Skip VPD module (convert byte size to word count) */
-               if (i == (u32)vpd_module) {
-                       i += (I40E_SR_VPD_MODULE_MAX_SIZE / 2);
-                       if (i >= hw->nvm.sr_size)
-                               break;
+               if ((i >= (u32)vpd_module) &&
+                   (i < ((u32)vpd_module +
+                    (I40E_SR_VPD_MODULE_MAX_SIZE / 2)))) {
+                       continue;
                }
                /* Skip PCIe ALT module (convert byte size to word count) */
-               if (i == (u32)pcie_alt_module) {
-                       i += (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2);
-                       if (i >= hw->nvm.sr_size)
-                               break;
+               if ((i >= (u32)pcie_alt_module) &&
+                   (i < ((u32)pcie_alt_module +
+                    (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2)))) {
+                       continue;
                }

-               ret_code = i40e_read_nvm_word(hw, (u16)i, &word);
-               if (ret_code != I40E_SUCCESS) {
-                       ret_code = I40E_ERR_NVM_CHECKSUM;
-                       goto i40e_calc_nvm_checksum_exit;
-               }
-               checksum_local += word;
+               checksum_local += data[i % I40E_SR_SECTOR_SIZE_IN_WORDS];
        }

        *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local;

 i40e_calc_nvm_checksum_exit:
+       i40e_free_virt_mem(hw, &vmem);
        return ret_code;
 }

-- 
1.8.1.4

Reply via email to