i40e/base: handle AQ timeout when releasing NVM
authorJingjing Wu <jingjing.wu@intel.com>
Sun, 6 Sep 2015 07:11:46 +0000 (15:11 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Thu, 1 Oct 2015 23:35:21 +0000 (01:35 +0200)
There are some rare cases where the release resource call will return an
admin Q timeout. In these cases the code needs to try to release the
resource again until it succeeds or it times out.

Also add little endian conversion for checksum

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
Tested-by: Huilong Xu <huilongx.xu@intel.com>
drivers/net/i40e/base/i40e_nvm.c

index 14b4e84..563d76a 100644 (file)
@@ -157,10 +157,26 @@ i40e_i40e_acquire_nvm_exit:
  **/
 void i40e_release_nvm(struct i40e_hw *hw)
 {
+       enum i40e_status_code ret_code = I40E_SUCCESS;
+       u32 total_delay = 0;
+
        DEBUGFUNC("i40e_release_nvm");
 
-       if (!hw->nvm.blank_nvm_mode)
-               i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
+       if (hw->nvm.blank_nvm_mode)
+               return;
+
+       ret_code = i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
+
+       /* there are some rare cases when trying to release the resource
+        * results in an admin Q timeout, so handle them correctly
+        */
+       while ((ret_code == I40E_ERR_ADMIN_QUEUE_TIMEOUT) &&
+              (total_delay < hw->aq.asq_cmd_timeout)) {
+                       i40e_msec_delay(1);
+                       ret_code = i40e_aq_release_resource(hw,
+                                               I40E_NVM_RESOURCE_ID, 0, NULL);
+                       total_delay++;
+       }
 }
 
 /**
@@ -587,6 +603,7 @@ enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
                /* 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;
@@ -632,13 +649,15 @@ enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw)
 {
        enum i40e_status_code ret_code = I40E_SUCCESS;
        u16 checksum;
+       __le16 le_sum;
 
        DEBUGFUNC("i40e_update_nvm_checksum");
 
        ret_code = i40e_calc_nvm_checksum(hw, &checksum);
+       le_sum = CPU_TO_LE16(checksum);
        if (ret_code == I40E_SUCCESS)
                ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
-                                            1, &checksum, true);
+                                            1, &le_sum, true);
 
        return ret_code;
 }