]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: iwlwifi: mld: don't modify trans state where not needed
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Tue, 26 Aug 2025 15:55:02 +0000 (18:55 +0300)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Thu, 28 Aug 2025 06:56:42 +0000 (09:56 +0300)
In suspend and resume flows, if we had any error we set the transport state to
'FW_ERROR' This was done to avoid sending commands when we shouldn't.

In the mentioned flows, we can have a few types of errors:
1. logic errors
2. FW is in error state (can't send commands)
3. FW is misbehaving
4. D3 handshake error

In the first, we can still talk to the firmware.
In the second - the transport already knows about the FW error, no need to tell it.
In the third - we need to treat it as any other FW misbehaviour. There is no reason
to have a special handling here.

So we only need it for the last type. Change the code to set the
tansport state to FW error only in case of a d3 handshake error.

While at it, add a comment explaining why the opmode sets the FW error
bits.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250826184046.44c74ac0eb2a.Ic7369e622d908684f9b25ffc293d14c167c26414@changeid
drivers/net/wireless/intel/iwlwifi/mld/d3.c
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c

index 5d24292c45a56ee9c8e8fc6de28da6d64231261a..8cd9d61a92e8373ba92f60fb07ea3a6b622ac418 100644 (file)
@@ -1212,6 +1212,9 @@ static int iwl_mld_wait_d3_notif(struct iwl_mld *mld,
 
        ret = iwl_trans_d3_resume(mld->trans, false);
        if (ret) {
+               /* Avoid sending commands if the FW is dead */
+               mld->trans->state = IWL_TRANS_NO_FW;
+               set_bit(STATUS_FW_ERROR, &mld->trans->status);
                iwl_remove_notification(&mld->notif_wait, &wait_d3_notif);
                return ret;
        }
@@ -1245,16 +1248,11 @@ int iwl_mld_no_wowlan_suspend(struct iwl_mld *mld)
 
        iwl_mld_low_latency_stop(mld);
 
-       /* This will happen if iwl_mld_supsend failed with FW error */
-       if (mld->trans->state == IWL_TRANS_NO_FW &&
-           test_bit(STATUS_FW_ERROR, &mld->trans->status))
-               return -ENODEV;
-
        ret = iwl_mld_update_device_power(mld, true);
        if (ret) {
                IWL_ERR(mld,
                        "d3 suspend: couldn't send power_device %d\n", ret);
-               goto out;
+               return ret;
        }
 
        ret = iwl_mld_send_cmd_pdu(mld, D3_CONFIG_CMD,
@@ -1262,24 +1260,21 @@ int iwl_mld_no_wowlan_suspend(struct iwl_mld *mld)
        if (ret) {
                IWL_ERR(mld,
                        "d3 suspend: couldn't send D3_CONFIG_CMD %d\n", ret);
-               goto out;
+               return ret;
        }
 
        ret = iwl_trans_d3_suspend(mld->trans, false);
        if (ret) {
                IWL_ERR(mld, "d3 suspend: trans_d3_suspend failed %d\n", ret);
+               /* We are going to stop the FW. Avoid sending commands in that flow */
+               mld->trans->state = IWL_TRANS_NO_FW;
+               set_bit(STATUS_FW_ERROR, &mld->trans->status);
        } else {
                /* Async notification might send hcmds, which is not allowed in suspend */
                iwl_mld_cancel_async_notifications(mld);
                mld->fw_status.in_d3 = true;
        }
 
- out:
-       if (ret) {
-               mld->trans->state = IWL_TRANS_NO_FW;
-               set_bit(STATUS_FW_ERROR, &mld->trans->status);
-       }
-
        return ret;
 }
 
@@ -1299,15 +1294,12 @@ int iwl_mld_no_wowlan_resume(struct iwl_mld *mld)
        iwl_fw_dbg_read_d3_debug_data(&mld->fwrt);
 
        ret = iwl_mld_wait_d3_notif(mld, &resume_data, false);
+       if (ret)
+               return ret;
 
        if (!ret && (resume_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE))
                return -ENODEV;
 
-       if (ret) {
-               mld->trans->state = IWL_TRANS_NO_FW;
-               set_bit(STATUS_FW_ERROR, &mld->trans->status);
-               return ret;
-       }
        iwl_mld_low_latency_restart(mld);
 
        return iwl_mld_update_device_power(mld, false);
@@ -1820,7 +1812,6 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
        };
        int link_id;
        int ret;
-       bool fw_err = false;
 
        lockdep_assert_wiphy(mld->wiphy);
 
@@ -1863,7 +1854,6 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
        ret = iwl_mld_wait_d3_notif(mld, &resume_data, true);
        if (ret) {
                IWL_ERR(mld, "Couldn't get the d3 notifs %d\n", ret);
-               fw_err = true;
                goto err;
        }
 
@@ -1900,11 +1890,6 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
        goto out;
 
  err:
-       if (fw_err) {
-               mld->trans->state = IWL_TRANS_NO_FW;
-               set_bit(STATUS_FW_ERROR, &mld->trans->status);
-       }
-
        mld->fw_status.in_hw_restart = true;
        ret = 1;
  out:
index f434012b03a63a68d8c230e6ca4b65705d0bb4be..debfb986a3873fb07263c85901bcce7f1d8de491 100644 (file)
@@ -1966,13 +1966,8 @@ iwl_mld_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
        iwl_fw_runtime_suspend(&mld->fwrt);
 
        ret = iwl_mld_wowlan_suspend(mld, wowlan);
-       if (ret) {
-               if (ret < 0) {
-                       mld->trans->state = IWL_TRANS_NO_FW;
-                       set_bit(STATUS_FW_ERROR, &mld->trans->status);
-               }
+       if (ret)
                return 1;
-       }
 
        if (iwl_mld_no_wowlan_suspend(mld))
                return 1;