iwlwifi: mvm: add support for new version for D0I3_END_CMD
During D3 state there are some flows which requires FW reset. Add new API to support it. Signed-off-by: Haim Dreyfuss <haim.dreyfuss@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
ee4cce9b9d
commit
d3b4dc014c
@ -64,6 +64,14 @@
|
||||
#ifndef __iwl_fw_api_d3_h__
|
||||
#define __iwl_fw_api_d3_h__
|
||||
|
||||
/**
|
||||
* enum iwl_d0i3_flags - d0i3 flags
|
||||
* @IWL_D0I3_RESET_REQUIRE: FW require reset upon resume
|
||||
*/
|
||||
enum iwl_d0i3_flags {
|
||||
IWL_D0I3_RESET_REQUIRE = BIT(0),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_d3_wakeup_flags - D3 manager wakeup flags
|
||||
* @IWL_WAKEUP_D3_CONFIG_FW_ERROR: wake up on firmware sysassert
|
||||
|
@ -1955,12 +1955,39 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
}
|
||||
|
||||
if (d0i3_first) {
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = D0I3_END_CMD,
|
||||
.flags = CMD_WANT_SKB,
|
||||
};
|
||||
int len;
|
||||
|
||||
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
||||
if (ret < 0) {
|
||||
IWL_ERR(mvm, "Failed to send D0I3_END_CMD first (%d)\n",
|
||||
ret);
|
||||
goto err;
|
||||
}
|
||||
switch (mvm->cmd_ver.d0i3_resp) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
|
||||
if (len != sizeof(u32)) {
|
||||
IWL_ERR(mvm,
|
||||
"Error with D0I3_END_CMD response size (%d)\n",
|
||||
len);
|
||||
goto err;
|
||||
}
|
||||
if (IWL_D0I3_RESET_REQUIRE &
|
||||
le32_to_cpu(*(__le32 *)cmd.resp_pkt->data)) {
|
||||
iwl_write32(mvm->trans, CSR_RESET,
|
||||
CSR_RESET_REG_FLAG_FORCE_NMI);
|
||||
iwl_free_resp(&cmd);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1122,6 +1122,10 @@ struct iwl_mvm {
|
||||
int responses[IWL_MVM_TOF_MAX_APS];
|
||||
} ftm_initiator;
|
||||
|
||||
struct {
|
||||
u8 d0i3_resp;
|
||||
} cmd_ver;
|
||||
|
||||
struct ieee80211_vif *nan_vif;
|
||||
#define IWL_MAX_BAID 32
|
||||
struct iwl_mvm_baid_data __rcu *baid_map[IWL_MAX_BAID];
|
||||
|
@ -608,6 +608,27 @@ static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = {
|
||||
.d3_debug_enable = iwl_mvm_d3_debug_enable,
|
||||
};
|
||||
|
||||
static u8 iwl_mvm_lookup_notif_ver(struct iwl_mvm *mvm, u8 grp, u8 cmd, u8 def)
|
||||
{
|
||||
const struct iwl_fw_cmd_version *entry;
|
||||
unsigned int i;
|
||||
|
||||
if (!mvm->fw->ucode_capa.cmd_versions ||
|
||||
!mvm->fw->ucode_capa.n_cmd_versions)
|
||||
return def;
|
||||
|
||||
entry = mvm->fw->ucode_capa.cmd_versions;
|
||||
for (i = 0; i < mvm->fw->ucode_capa.n_cmd_versions; i++, entry++) {
|
||||
if (entry->group == grp && entry->cmd == cmd) {
|
||||
if (entry->notif_ver == IWL_FW_CMD_VER_UNKNOWN)
|
||||
return def;
|
||||
return entry->notif_ver;
|
||||
}
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
static struct iwl_op_mode *
|
||||
iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
const struct iwl_fw *fw, struct dentry *dbgfs_dir)
|
||||
@ -722,6 +743,12 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
|
||||
INIT_DELAYED_WORK(&mvm->cs_tx_unblock_dwork, iwl_mvm_tx_unblock_dwork);
|
||||
|
||||
mvm->cmd_ver.d0i3_resp =
|
||||
iwl_mvm_lookup_notif_ver(mvm, LEGACY_GROUP, D0I3_END_CMD, 0);
|
||||
/* we only support version 1 */
|
||||
if (WARN_ON_ONCE(mvm->cmd_ver.d0i3_resp > 1))
|
||||
goto out_free;
|
||||
|
||||
/*
|
||||
* Populate the state variables that the transport layer needs
|
||||
* to know about.
|
||||
|
Loading…
Reference in New Issue
Block a user