diff options
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-trans.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 29 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mld/d3.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mld/mld.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 6 |
7 files changed, 27 insertions, 66 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c index aaade854b8b7..7a56a79ff014 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c @@ -327,17 +327,7 @@ int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) test_bit(STATUS_RFKILL_OPMODE, &trans->status))) return -ERFKILL; - /* - * We can't test IWL_MVM_STATUS_IN_D3 in mvm->status because this - * bit is set early in the D3 flow, before we send all the commands - * that configure the firmware for D3 operation (power, patterns, ...) - * and we don't want to flag all those with CMD_SEND_IN_D3. - * So use the system_pm_mode instead. The only command sent after - * we set system_pm_mode is D3_CONFIG_CMD, which we now flag with - * CMD_SEND_IN_D3. - */ - if (unlikely(trans->system_pm_mode == IWL_PLAT_PM_MODE_D3 && - !(cmd->flags & CMD_SEND_IN_D3))) + if (unlikely(test_bit(STATUS_SUSPENDED, &trans->status))) return -EHOSTDOWN; if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) @@ -420,6 +410,8 @@ int iwl_trans_start_hw(struct iwl_trans *trans) might_sleep(); clear_bit(STATUS_TRANS_RESET_IN_PROGRESS, &trans->status); + /* opmode may not resume if it detects errors */ + clear_bit(STATUS_SUSPENDED, &trans->status); return iwl_trans_pcie_start_hw(trans); } @@ -510,18 +502,31 @@ IWL_EXPORT_SYMBOL(iwl_trans_dump_data); int iwl_trans_d3_suspend(struct iwl_trans *trans, bool test, bool reset) { + int err; + might_sleep(); - return iwl_trans_pcie_d3_suspend(trans, test, reset); + err = iwl_trans_pcie_d3_suspend(trans, test, reset); + + if (!err) + set_bit(STATUS_SUSPENDED, &trans->status); + + return err; } IWL_EXPORT_SYMBOL(iwl_trans_d3_suspend); int iwl_trans_d3_resume(struct iwl_trans *trans, enum iwl_d3_status *status, bool test, bool reset) { + int err; + might_sleep(); - return iwl_trans_pcie_d3_resume(trans, status, test, reset); + err = iwl_trans_pcie_d3_resume(trans, status, test, reset); + + clear_bit(STATUS_SUSPENDED, &trans->status); + + return err; } IWL_EXPORT_SYMBOL(iwl_trans_d3_resume); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 3a3bc5d4f405..72512ecf897f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -109,16 +109,12 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt) * the response. The caller needs to call iwl_free_resp when done. * @CMD_SEND_IN_RFKILL: Send the command even if the NIC is in RF-kill. * @CMD_BLOCK_TXQS: Block TXQs while the comment is executing. - * @CMD_SEND_IN_D3: Allow the command to be sent in D3 mode, relevant to - * SUSPEND and RESUME commands. We are in D3 mode when we set - * trans->system_pm_mode to IWL_PLAT_PM_MODE_D3. */ enum CMD_MODE { CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), CMD_SEND_IN_RFKILL = BIT(2), CMD_BLOCK_TXQS = BIT(3), - CMD_SEND_IN_D3 = BIT(4), }; #define CMD_MODE_BITS 5 @@ -306,6 +302,8 @@ enum iwl_d3_status { * the firmware state yet * @STATUS_TRANS_RESET_IN_PROGRESS: reset is still in progress, don't * attempt another reset yet + * @STATUS_SUSPENDED: device is suspended, don't send commands that + * aren't marked accordingly */ enum iwl_trans_status { STATUS_SYNC_HCMD_ACTIVE, @@ -320,6 +318,7 @@ enum iwl_trans_status { STATUS_IN_SW_RESET, STATUS_RESET_PENDING, STATUS_TRANS_RESET_IN_PROGRESS, + STATUS_SUSPENDED, }; static inline int @@ -517,23 +516,6 @@ enum iwl_trans_state { */ /** - * enum iwl_plat_pm_mode - platform power management mode - * - * This enumeration describes the device's platform power management - * behavior when in system-wide suspend (i.e WoWLAN). - * - * @IWL_PLAT_PM_MODE_DISABLED: power management is disabled for this - * device. In system-wide suspend mode, it means that the all - * connections will be closed automatically by mac80211 before - * the platform is suspended. - * @IWL_PLAT_PM_MODE_D3: the device goes into D3 mode (i.e. WoWLAN). - */ -enum iwl_plat_pm_mode { - IWL_PLAT_PM_MODE_DISABLED, - IWL_PLAT_PM_MODE_D3, -}; - -/** * enum iwl_ini_cfg_state * @IWL_INI_CFG_STATE_NOT_LOADED: no debug cfg was given * @IWL_INI_CFG_STATE_LOADED: debug cfg was found and loaded @@ -869,9 +851,6 @@ struct iwl_txq { * start of the 802.11 header in the @rx_mpdu_cmd * @dbg: additional debug data, see &struct iwl_trans_debug * @init_dram: FW initialization DMA data - * @system_pm_mode: the system-wide power management mode in use. - * This mode is set dynamically, depending on the WoWLAN values - * configured from the userspace at runtime. * @name: the device name * @mbx_addr_0_step: step address data 0 * @mbx_addr_1_step: step address data 1 @@ -951,8 +930,6 @@ struct iwl_trans { struct iwl_trans_debug dbg; struct iwl_self_init_dram init_dram; - enum iwl_plat_pm_mode system_pm_mode; - const char *name; u32 mbx_addr_0_step; u32 mbx_addr_1_step; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index 21b20e07aab4..f90043728689 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -1346,7 +1346,6 @@ int iwl_mld_no_wowlan_suspend(struct iwl_mld *mld) } else { /* Async notification might send hcmds, which is not allowed in suspend */ iwl_mld_cancel_async_notifications(mld); - mld->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; mld->fw_status.in_d3 = true; } @@ -1371,7 +1370,6 @@ int iwl_mld_no_wowlan_resume(struct iwl_mld *mld) IWL_DEBUG_WOWLAN(mld, "Starting the no wowlan resume flow\n"); - mld->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; mld->fw_status.in_d3 = false; iwl_fw_dbg_read_d3_debug_data(&mld->fwrt); @@ -1902,7 +1900,6 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld) IWL_DEBUG_WOWLAN(mld, "Starting the wowlan resume flow\n"); - mld->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; if (!mld->fw_status.in_d3) { IWL_DEBUG_WOWLAN(mld, "Device_powered_off() was called during wowlan\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index e26fcce773aa..81a4443d3b4c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -710,7 +710,6 @@ static void iwl_mld_device_powered_off(struct iwl_op_mode *op_mode) struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode); wiphy_lock(mld->wiphy); - mld->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; iwl_mld_stop_fw(mld); mld->fw_status.in_d3 = false; wiphy_unlock(mld->wiphy); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 3e8b7168af01..456ad4fadd8f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -1266,7 +1266,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, }; struct iwl_host_cmd d3_cfg_cmd = { .id = D3_CONFIG_CMD, - .flags = CMD_WANT_SKB | CMD_SEND_IN_D3, + .flags = CMD_WANT_SKB, .data[0] = &d3_cfg_cmd_data, .len[0] = sizeof(d3_cfg_cmd_data), }; @@ -1373,8 +1373,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true); - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; - /* must be last -- this switches firmware state */ ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); if (ret) @@ -3407,9 +3405,9 @@ static int iwl_mvm_resume_firmware(struct iwl_mvm *mvm, bool test) int ret; enum iwl_d3_status d3_status; struct iwl_host_cmd cmd = { - .id = D0I3_END_CMD, - .flags = CMD_WANT_SKB | CMD_SEND_IN_D3, - }; + .id = D0I3_END_CMD, + .flags = CMD_WANT_SKB, + }; bool reset = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); @@ -3564,9 +3562,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_WOWLAN); - /* after the successful handshake, we're out of D3 */ - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; - /* when reset is required we can't send these following commands */ if (d3_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE) goto query_wakeup_reasons; @@ -3639,9 +3634,6 @@ out: */ set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); - /* regardless of what happened, we're now out of D3 */ - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; - return 1; } @@ -3679,8 +3671,7 @@ void iwl_mvm_fast_suspend(struct iwl_mvm *mvm) set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); WARN_ON(iwl_mvm_power_update_device(mvm)); - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; - ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SEND_IN_D3, + ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, 0, sizeof(d3_cfg_cmd_data), &d3_cfg_cmd_data); if (ret) IWL_ERR(mvm, @@ -3735,7 +3726,6 @@ int iwl_mvm_fast_resume(struct iwl_mvm *mvm) out: clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; mvm->fast_resume = false; return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 5c7c1d53a28d..5629aa0a91fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -2126,7 +2126,6 @@ static void iwl_op_mode_mvm_device_powered_off(struct iwl_op_mode *op_mode) mutex_lock(&mvm->mutex); clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; iwl_mvm_stop_device(mvm); mvm->fast_resume = false; mutex_unlock(&mvm->mutex); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 3c86a5f23d8f..7d7a217b1575 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -2659,12 +2659,6 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, return -ERFKILL; } - if (unlikely(trans->system_pm_mode == IWL_PLAT_PM_MODE_D3 && - !(cmd->flags & CMD_SEND_IN_D3))) { - IWL_DEBUG_WOWLAN(trans, "Dropping CMD 0x%x: D3\n", cmd->id); - return -EHOSTDOWN; - } - if (cmd->flags & CMD_ASYNC) { int ret; |