i40e/base: enhance NVM checksum calculation
authorHelin Zhang <helin.zhang@intel.com>
Thu, 30 Apr 2015 15:03:20 +0000 (23:03 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Fri, 15 May 2015 14:33:16 +0000 (16:33 +0200)
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.

Test report: http://www.dpdk.org/ml/archives/dev/2015-May/017384.html

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
Acked-by: Jijiang Liu <jijiang.liu@intel.com>
Tested-by: Min Cao <min.cao@intel.com>
lib/librte_pmd_i40e/i40e/i40e_nvm.c

index 47a4285..f1a1e88 100644 (file)
@@ -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;
 }