Commit 7aeec8c8 authored by Johannes Berg's avatar Johannes Berg Committed by Miri Korenblit
Browse files

wifi: iwlwifi: remove PM mode and send-in-D3



Simplify the logic here by tracking only suspended as a
status bit, and remove CMD_SEND_IN_D3 completely. There
is no value, since the op-mode sets the state and also
sends the commands.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Reviewed-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250503224231.cc3360761f1e.I72261afc42cee8983198b4660b7d38b7df7963da@changeid
parent 11074fce
Loading
Loading
Loading
Loading
+18 −13
Original line number Diff line number Diff line
@@ -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);

+3 −26
Original line number Diff line number Diff line
@@ -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
@@ -516,23 +515,6 @@ enum iwl_trans_state {
 * be confused with the physical device power 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
@@ -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;
+0 −3
Original line number Diff line number Diff line
@@ -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");
+0 −1
Original line number Diff line number Diff line
@@ -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);
+6 −16
Original line number Diff line number Diff line
// 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)
@@ -3408,7 +3406,7 @@ static int iwl_mvm_resume_firmware(struct iwl_mvm *mvm, bool test)
	enum iwl_d3_status d3_status;
	struct iwl_host_cmd cmd = {
		.id = D0I3_END_CMD,
			.flags = CMD_WANT_SKB | CMD_SEND_IN_D3,
		.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 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
	 */
	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;
Loading