> -----Original Message-----
> From: Intel-wired-lan <[email protected]> On Behalf
> Of Robert Malz via Intel-wired-lan
> Sent: Wednesday, June 17, 2026 12:08 AM
> To: Nguyen, Anthony L <[email protected]>; Kitszel,
> Przemyslaw <[email protected]>
> Cc: [email protected]; [email protected]
> Subject: [Intel-wired-lan] [PATCH v2] ice: retry reading NVM if
> admin queue returns EBUSY
>
> When the admin queue command to read NVM returns EBUSY, the driver
> currently treats it as a fatal error and aborts the entire read
> operation. This can cause spurious NVM read failures during periods
> of high firmware activity.
>
> Add retry logic to ice_read_flat_nvm() that handles EBUSY responses
> from the admin queue. When an EBUSY error is encountered, release
> the NVM resource lock, wait for ICE_SQ_SEND_DELAY_TIME_MS, re-
> acquire it, and retry the failed read. The retry is attempted up to
> ICE_SQ_SEND_MAX_EXECUTE times before giving up.
>
> Code was extracted from OOT ice driver 1.15.4 release. Additional
> change was made to reset last_cmd in case of retry to make sure that
> all commands are retried properly.
>
> Fixes: e94509906d6b ("ice: create function to read a section of the
> NVM and Shadow RAM")
> Signed-off-by: Robert Malz <[email protected]>
> ---
> Changes in v2:
> - change ICE_AQ_RC_EBUSY -> LIBIE_AQ_RC_EBUSY
>
> drivers/net/ethernet/intel/ice/ice_nvm.c | 25 +++++++++++++++++++--
> ---
> 1 file changed, 20 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.c
> b/drivers/net/ethernet/intel/ice/ice_nvm.c
> index 7e187a804dfa..b3120605d66f 100644
> --- a/drivers/net/ethernet/intel/ice/ice_nvm.c
> +++ b/drivers/net/ethernet/intel/ice/ice_nvm.c
> @@ -67,6 +67,7 @@ ice_read_flat_nvm(struct ice_hw *hw, u32 offset,
> u32 *length, u8 *data, {
> u32 inlen = *length;
> u32 bytes_read = 0;
> + int retry_cnt = 0;
> bool last_cmd;
> int status;
>
> @@ -96,11 +97,25 @@ ice_read_flat_nvm(struct ice_hw *hw, u32 offset,
> u32 *length, u8 *data,
> offset, read_size,
> data + bytes_read, last_cmd,
> read_shadow_ram, NULL);
> - if (status)
> - break;
> -
> - bytes_read += read_size;
> - offset += read_size;
> + if (status) {
> + if (hw->adminq.sq_last_status !=
> LIBIE_AQ_RC_EBUSY ||
> + retry_cnt > ICE_SQ_SEND_MAX_EXECUTE)
> + break;
> + ice_debug(hw, ICE_DBG_NVM,
> + "NVM read EBUSY error, retry %d\n",
> + retry_cnt + 1);
> + last_cmd = false;
> + ice_release_nvm(hw);
> + msleep(ICE_SQ_SEND_DELAY_TIME_MS);
> + status = ice_acquire_nvm(hw, ICE_RES_READ);
> + if (status)
> + break;
> + retry_cnt++;
It looks like you added the retry_cnt increment but you didn't add it into the
loop exit condition.
> + } else {
> + bytes_read += read_size;
> + offset += read_size;
> + retry_cnt = 0;
> + }
> } while (!last_cmd);
>
> *length = bytes_read;
> --
> 2.34.1