i40e/i40evf: add wait states to NVM state machine
authorShannon Nelson <shannon.nelson@intel.com>
Fri, 28 Aug 2015 21:55:49 +0000 (17:55 -0400)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 18 Sep 2015 00:47:16 +0000 (17:47 -0700)
This adds wait states to the NVM update state machine to signify when
waiting for an update operation to finish, whether we're in the middle
of a set of Write operations, or we're now idle but waiting.

Change-ID: Iabe91d6579ef6a2ea560647e374035656211ab43
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_adminq.c
drivers/net/ethernet/intel/i40e/i40e_nvm.c
drivers/net/ethernet/intel/i40e/i40e_type.h
drivers/net/ethernet/intel/i40evf/i40e_type.h

index 8a77f59f57aa8070e64ad4d691d4d9f428d25ab1..ea1e930b52cf23aa48ff7448bdf67c29617f6b3d 100644 (file)
@@ -1018,6 +1018,19 @@ clean_arq_element_out:
                        i40e_release_nvm(hw);
                        hw->aq.nvm_release_on_done = false;
                }
+
+               switch (hw->nvmupd_state) {
+               case I40E_NVMUPD_STATE_INIT_WAIT:
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+                       break;
+
+               case I40E_NVMUPD_STATE_WRITE_WAIT:
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
+                       break;
+
+               default:
+                       break;
+               }
        }
 
        return ret_code;
index 7ff309945d6f06a680e59667394aee784cc9370b..7bcbe59ae47eaec595434a91c5a349071c056b3f 100644 (file)
@@ -696,6 +696,12 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
                status = i40e_nvmupd_state_writing(hw, cmd, bytes, perrno);
                break;
 
+       case I40E_NVMUPD_STATE_INIT_WAIT:
+       case I40E_NVMUPD_STATE_WRITE_WAIT:
+               status = I40E_ERR_NOT_READY;
+               *perrno = -EBUSY;
+               break;
+
        default:
                /* invalid state, should never happen */
                i40e_debug(hw, I40E_DEBUG_NVM,
@@ -759,10 +765,12 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
                                                     hw->aq.asq_last_status);
                } else {
                        status = i40e_nvmupd_nvm_erase(hw, cmd, perrno);
-                       if (status)
+                       if (status) {
                                i40e_release_nvm(hw);
-                       else
+                       } else {
                                hw->aq.nvm_release_on_done = true;
+                               hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
+                       }
                }
                break;
 
@@ -773,10 +781,12 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
                                                     hw->aq.asq_last_status);
                } else {
                        status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
-                       if (status)
+                       if (status) {
                                i40e_release_nvm(hw);
-                       else
+                       } else {
                                hw->aq.nvm_release_on_done = true;
+                               hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
+                       }
                }
                break;
 
@@ -790,7 +800,7 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
                        if (status)
                                i40e_release_nvm(hw);
                        else
-                               hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
+                               hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
                }
                break;
 
@@ -809,6 +819,7 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
                                i40e_release_nvm(hw);
                        } else {
                                hw->aq.nvm_release_on_done = true;
+                               hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
                        }
                }
                break;
@@ -838,7 +849,7 @@ static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
                                             struct i40e_nvm_access *cmd,
                                             u8 *bytes, int *perrno)
 {
-       i40e_status status;
+       i40e_status status = 0;
        enum i40e_nvmupd_cmd upd_cmd;
 
        upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
@@ -880,7 +891,7 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
                                             struct i40e_nvm_access *cmd,
                                             u8 *bytes, int *perrno)
 {
-       i40e_status status;
+       i40e_status status = 0;
        enum i40e_nvmupd_cmd upd_cmd;
        bool retry_attempt = false;
 
@@ -890,13 +901,22 @@ retry:
        switch (upd_cmd) {
        case I40E_NVMUPD_WRITE_CON:
                status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
+               if (!status)
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
                break;
 
        case I40E_NVMUPD_WRITE_LCB:
                status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
-               if (!status)
+               if (status) {
+                       *perrno = hw->aq.asq_last_status ?
+                                  i40e_aq_rc_to_posix(status,
+                                                      hw->aq.asq_last_status) :
+                                  -EIO;
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+               } else {
                        hw->aq.nvm_release_on_done = true;
-               hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
+               }
                break;
 
        case I40E_NVMUPD_CSUM_CON:
@@ -907,19 +927,23 @@ retry:
                                                       hw->aq.asq_last_status) :
                                   -EIO;
                        hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+               } else {
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
                }
                break;
 
        case I40E_NVMUPD_CSUM_LCB:
                status = i40e_update_nvm_checksum(hw);
-               if (status)
+               if (status) {
                        *perrno = hw->aq.asq_last_status ?
                                   i40e_aq_rc_to_posix(status,
                                                       hw->aq.asq_last_status) :
                                   -EIO;
-               else
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+               } else {
                        hw->aq.nvm_release_on_done = true;
-               hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
+               }
                break;
 
        default:
index f63f538d75c58b8d4295b20738371dd4e7653ee1..3f799301649451acadb97a7e05779d7dd0f7e974 100644 (file)
@@ -311,7 +311,9 @@ enum i40e_nvmupd_cmd {
 enum i40e_nvmupd_state {
        I40E_NVMUPD_STATE_INIT,
        I40E_NVMUPD_STATE_READING,
-       I40E_NVMUPD_STATE_WRITING
+       I40E_NVMUPD_STATE_WRITING,
+       I40E_NVMUPD_STATE_INIT_WAIT,
+       I40E_NVMUPD_STATE_WRITE_WAIT,
 };
 
 /* nvm_access definition and its masks/shifts need to be accessible to
index 7f3c05c7655e7d6c8adfc2098fbf749c168524b4..439a4e1f2689f434ac2aaceda0ad1a74ac712296 100644 (file)
@@ -310,7 +310,9 @@ enum i40e_nvmupd_cmd {
 enum i40e_nvmupd_state {
        I40E_NVMUPD_STATE_INIT,
        I40E_NVMUPD_STATE_READING,
-       I40E_NVMUPD_STATE_WRITING
+       I40E_NVMUPD_STATE_WRITING,
+       I40E_NVMUPD_STATE_INIT_WAIT,
+       I40E_NVMUPD_STATE_WRITE_WAIT,
 };
 
 /* nvm_access definition and its masks/shifts need to be accessible to