aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/i40e/i40e_nvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_nvm.c')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_nvm.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 28429c8fbc98..039018abad4a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -725,9 +725,11 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
725{ 725{
726 i40e_status status; 726 i40e_status status;
727 enum i40e_nvmupd_cmd upd_cmd; 727 enum i40e_nvmupd_cmd upd_cmd;
728 bool retry_attempt = false;
728 729
729 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno); 730 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
730 731
732retry:
731 switch (upd_cmd) { 733 switch (upd_cmd) {
732 case I40E_NVMUPD_WRITE_CON: 734 case I40E_NVMUPD_WRITE_CON:
733 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno); 735 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
@@ -771,6 +773,39 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
771 *errno = -ESRCH; 773 *errno = -ESRCH;
772 break; 774 break;
773 } 775 }
776
777 /* In some circumstances, a multi-write transaction takes longer
778 * than the default 3 minute timeout on the write semaphore. If
779 * the write failed with an EBUSY status, this is likely the problem,
780 * so here we try to reacquire the semaphore then retry the write.
781 * We only do one retry, then give up.
782 */
783 if (status && (hw->aq.asq_last_status == I40E_AQ_RC_EBUSY) &&
784 !retry_attempt) {
785 i40e_status old_status = status;
786 u32 old_asq_status = hw->aq.asq_last_status;
787 u32 gtime;
788
789 gtime = rd32(hw, I40E_GLVFGEN_TIMER);
790 if (gtime >= hw->nvm.hw_semaphore_timeout) {
791 i40e_debug(hw, I40E_DEBUG_ALL,
792 "NVMUPD: write semaphore expired (%d >= %lld), retrying\n",
793 gtime, hw->nvm.hw_semaphore_timeout);
794 i40e_release_nvm(hw);
795 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
796 if (status) {
797 i40e_debug(hw, I40E_DEBUG_ALL,
798 "NVMUPD: write semaphore reacquire failed aq_err = %d\n",
799 hw->aq.asq_last_status);
800 status = old_status;
801 hw->aq.asq_last_status = old_asq_status;
802 } else {
803 retry_attempt = true;
804 goto retry;
805 }
806 }
807 }
808
774 return status; 809 return status;
775} 810}
776 811