From 3ed6c3246f432993afcdbd8148b4c5d91303bc21 Mon Sep 17 00:00:00 2001 From: Jingjing Wu Date: Sun, 6 Sep 2015 15:11:46 +0800 Subject: [PATCH] i40e/base: handle AQ timeout when releasing NVM 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 Acked-by: Helin Zhang Tested-by: Huilong Xu --- drivers/net/i40e/base/i40e_nvm.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/net/i40e/base/i40e_nvm.c b/drivers/net/i40e/base/i40e_nvm.c index 14b4e84c87..563d76aad0 100644 --- a/drivers/net/i40e/base/i40e_nvm.c +++ b/drivers/net/i40e/base/i40e_nvm.c @@ -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; } -- 2.20.1