Commit 762c523f authored by Gil Adam's avatar Gil Adam Committed by Luca Coelho

iwlwifi: thermal: support new temperature measurement API

New API for temperature measurement (DTS_MEASUREMENT_TRIGGER)
involves getting an immediate response from FW, and not waiting
for a notification like in previous APIs. Support new API while
keeping backwards compatibility.
Signed-off-by: default avatarGil Adam <gil.adam@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20200930161256.b4893554d8e7.Ia4d7f389d4ac3256fcfe3ce6144e924dd6dbf6eb@changeidSigned-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 42f8a273
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* Copyright(c) 2019 Intel Corporation * Copyright(c) 2019 - 2020 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* Copyright(c) 2019 Intel Corporation * Copyright(c) 2019 - 2020 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -213,6 +213,15 @@ struct iwl_dts_measurement_notif_v2 { ...@@ -213,6 +213,15 @@ struct iwl_dts_measurement_notif_v2 {
__le32 threshold_idx; __le32 threshold_idx;
} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_2 */ } __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_2 */
/**
* struct iwl_dts_measurement_resp - measurements response
*
* @temp: the measured temperature
*/
struct iwl_dts_measurement_resp {
__le32 temp;
} __packed; /* CMD_DTS_MEASUREMENT_RSP_API_S_VER_1 */
/** /**
* struct ct_kill_notif - CT-kill entry notification * struct ct_kill_notif - CT-kill entry notification
* *
......
...@@ -228,24 +228,67 @@ void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) ...@@ -228,24 +228,67 @@ void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
iwl_mvm_enter_ctkill(mvm); iwl_mvm_enter_ctkill(mvm);
} }
static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm) /*
* send the DTS_MEASUREMENT_TRIGGER command with or without waiting for a
* response. If we get a response then the measurement is stored in 'temp'
*/
static int iwl_mvm_send_temp_cmd(struct iwl_mvm *mvm, bool response, s32 *temp)
{ {
struct iwl_dts_measurement_cmd cmd = { struct iwl_host_cmd cmd = {};
struct iwl_dts_measurement_cmd dts_cmd = {
.flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP), .flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP),
}; };
struct iwl_ext_dts_measurement_cmd extcmd = { struct iwl_ext_dts_measurement_cmd ext_cmd = {
.control_mode = cpu_to_le32(DTS_DIRECT_WITHOUT_MEASURE), .control_mode = cpu_to_le32(DTS_DIRECT_WITHOUT_MEASURE),
}; };
u32 cmdid; struct iwl_dts_measurement_resp *resp;
void *cmd_ptr;
int ret;
u32 cmd_flags = 0;
u16 len;
/* Check which command format is used (regular/extended) */
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE)) {
len = sizeof(ext_cmd);
cmd_ptr = &ext_cmd;
} else {
len = sizeof(dts_cmd);
cmd_ptr = &dts_cmd;
}
/* The command version where we get a response is zero length */
if (response) {
cmd_flags = CMD_WANT_SKB;
len = 0;
}
cmdid = iwl_cmd_id(CMD_DTS_MEASUREMENT_TRIGGER_WIDE, cmd.id = WIDE_ID(PHY_OPS_GROUP, CMD_DTS_MEASUREMENT_TRIGGER_WIDE);
PHY_OPS_GROUP, 0); cmd.len[0] = len;
cmd.flags = cmd_flags;
cmd.data[0] = cmd_ptr;
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_DEBUG_TEMP(mvm,
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE)) "Sending temperature measurement command - %s response\n",
return iwl_mvm_send_cmd_pdu(mvm, cmdid, 0, sizeof(cmd), &cmd); response ? "with" : "without");
ret = iwl_mvm_send_cmd(mvm, &cmd);
return iwl_mvm_send_cmd_pdu(mvm, cmdid, 0, sizeof(extcmd), &extcmd); if (ret) {
IWL_ERR(mvm,
"Failed to send the temperature measurement command (err=%d)\n",
ret);
return ret;
}
if (response) {
resp = (void *)cmd.resp_pkt->data;
*temp = le32_to_cpu(resp->temp);
IWL_DEBUG_TEMP(mvm,
"Got temperature measurement response: temp=%d\n",
*temp);
iwl_free_resp(&cmd);
}
return ret;
} }
int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp) int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp)
...@@ -254,6 +297,18 @@ int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp) ...@@ -254,6 +297,18 @@ int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp)
static u16 temp_notif[] = { WIDE_ID(PHY_OPS_GROUP, static u16 temp_notif[] = { WIDE_ID(PHY_OPS_GROUP,
DTS_MEASUREMENT_NOTIF_WIDE) }; DTS_MEASUREMENT_NOTIF_WIDE) };
int ret; int ret;
u8 cmd_ver;
/*
* If command version is 1 we send the command and immediately get
* a response. For older versions we send the command and wait for a
* notification (no command TLV for previous versions).
*/
cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_OPS_GROUP,
CMD_DTS_MEASUREMENT_TRIGGER_WIDE,
IWL_FW_CMD_VER_UNKNOWN);
if (cmd_ver == 1)
return iwl_mvm_send_temp_cmd(mvm, true, temp);
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
...@@ -261,9 +316,8 @@ int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp) ...@@ -261,9 +316,8 @@ int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp)
temp_notif, ARRAY_SIZE(temp_notif), temp_notif, ARRAY_SIZE(temp_notif),
iwl_mvm_temp_notif_wait, temp); iwl_mvm_temp_notif_wait, temp);
ret = iwl_mvm_get_temp_cmd(mvm); ret = iwl_mvm_send_temp_cmd(mvm, false, temp);
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to get the temperature (err=%d)\n", ret);
iwl_remove_notification(&mvm->notif_wait, &wait_temp_notif); iwl_remove_notification(&mvm->notif_wait, &wait_temp_notif);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment