diff options
author | Chaya Rachel Ivgi <chaya.rachel.ivgi@intel.com> | 2015-12-16 09:34:55 -0500 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2016-02-27 14:59:48 -0500 |
commit | 0a3b7119000d706dfbc7e0c5b66e192a646d365f (patch) | |
tree | f0609fcce239aaaebe827243627fddb0a9514958 | |
parent | 51bcc7386a01074452c585e421a24dfc7b19063b (diff) |
iwlwifi: mvm: add CT-KILL notification
Up to today the driver was notified of the temperature from the FW
and decided whether to enter CT-kill or not.
From now on, the FW will decide when to enter CT-kill and will notify
the driver.
Add support for this notification.
Signed-off-by: Chaya Rachel Ivgi <chaya.rachel.ivgi@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 15 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 27 |
5 files changed, 61 insertions, 1 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h index e2dbc67a367b..724a3eef78b1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h | |||
@@ -318,6 +318,9 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t; | |||
318 | * @IWL_UCODE_TLV_CAPA_BEACON_STORING: firmware will store the latest beacon | 318 | * @IWL_UCODE_TLV_CAPA_BEACON_STORING: firmware will store the latest beacon |
319 | * from AP and will send it upon d0i3 exit. | 319 | * from AP and will send it upon d0i3 exit. |
320 | * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2: support LAR API V2 | 320 | * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2: support LAR API V2 |
321 | * @IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW: firmware responsible for CT-kill | ||
322 | * @IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT: supports temperature | ||
323 | * thresholds reporting | ||
321 | * | 324 | * |
322 | * @NUM_IWL_UCODE_TLV_CAPA: number of bits used | 325 | * @NUM_IWL_UCODE_TLV_CAPA: number of bits used |
323 | */ | 326 | */ |
@@ -351,6 +354,8 @@ enum iwl_ucode_tlv_capa { | |||
351 | IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION = (__force iwl_ucode_tlv_capa_t)71, | 354 | IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION = (__force iwl_ucode_tlv_capa_t)71, |
352 | IWL_UCODE_TLV_CAPA_BEACON_STORING = (__force iwl_ucode_tlv_capa_t)72, | 355 | IWL_UCODE_TLV_CAPA_BEACON_STORING = (__force iwl_ucode_tlv_capa_t)72, |
353 | IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2 = (__force iwl_ucode_tlv_capa_t)73, | 356 | IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2 = (__force iwl_ucode_tlv_capa_t)73, |
357 | IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW = (__force iwl_ucode_tlv_capa_t)74, | ||
358 | IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT = (__force iwl_ucode_tlv_capa_t)75, | ||
354 | 359 | ||
355 | NUM_IWL_UCODE_TLV_CAPA | 360 | NUM_IWL_UCODE_TLV_CAPA |
356 | #ifdef __CHECKER__ | 361 | #ifdef __CHECKER__ |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index f332497e29d1..ecbf7cb600ce 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | |||
@@ -279,6 +279,7 @@ enum { | |||
279 | */ | 279 | */ |
280 | enum iwl_phy_ops_subcmd_ids { | 280 | enum iwl_phy_ops_subcmd_ids { |
281 | CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0, | 281 | CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0, |
282 | CT_KILL_NOTIFICATION = 0xFE, | ||
282 | DTS_MEASUREMENT_NOTIF_WIDE = 0xFF, | 283 | DTS_MEASUREMENT_NOTIF_WIDE = 0xFF, |
283 | }; | 284 | }; |
284 | 285 | ||
@@ -1685,6 +1686,17 @@ struct iwl_dts_measurement_notif { | |||
1685 | __le32 voltage; | 1686 | __le32 voltage; |
1686 | } __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */ | 1687 | } __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */ |
1687 | 1688 | ||
1689 | /** | ||
1690 | * struct ct_kill_notif - CT-kill entry notification | ||
1691 | * | ||
1692 | * @temperature: the current temperature in celsius | ||
1693 | * @reserved: reserved | ||
1694 | */ | ||
1695 | struct ct_kill_notif { | ||
1696 | __le16 temperature; | ||
1697 | __le16 reserved; | ||
1698 | } __packed; /* GRP_PHY_CT_KILL_NTF */ | ||
1699 | |||
1688 | /*********************************** | 1700 | /*********************************** |
1689 | * TDLS API | 1701 | * TDLS API |
1690 | ***********************************/ | 1702 | ***********************************/ |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index ebe37bb0ce4c..200bbb76ff0a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | |||
@@ -7,6 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
10 | * Copyright(c) 2016 Intel Deutschland GmbH | ||
10 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of version 2 of the GNU General Public License as | 13 | * it under the terms of version 2 of the GNU General Public License as |
@@ -33,6 +34,7 @@ | |||
33 | * | 34 | * |
34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 35 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 36 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
37 | * Copyright(c) 2016 Intel Deutschland GmbH | ||
36 | * All rights reserved. | 38 | * All rights reserved. |
37 | * | 39 | * |
38 | * Redistribution and use in source and binary forms, with or without | 40 | * Redistribution and use in source and binary forms, with or without |
@@ -1028,6 +1030,18 @@ static inline bool iwl_mvm_has_new_rx_api(struct iwl_mvm *mvm) | |||
1028 | IWL_UCODE_TLV_CAPA_MULTI_QUEUE_RX_SUPPORT); | 1030 | IWL_UCODE_TLV_CAPA_MULTI_QUEUE_RX_SUPPORT); |
1029 | } | 1031 | } |
1030 | 1032 | ||
1033 | static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm) | ||
1034 | { | ||
1035 | /* these two TLV are redundant since the responsibility to CT-kill by | ||
1036 | * FW happens only after we send at least one command of | ||
1037 | * temperature THs report. | ||
1038 | */ | ||
1039 | return fw_has_capa(&mvm->fw->ucode_capa, | ||
1040 | IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW) && | ||
1041 | fw_has_capa(&mvm->fw->ucode_capa, | ||
1042 | IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT); | ||
1043 | } | ||
1044 | |||
1031 | extern const u8 iwl_mvm_ac_to_tx_fifo[]; | 1045 | extern const u8 iwl_mvm_ac_to_tx_fifo[]; |
1032 | 1046 | ||
1033 | struct iwl_rate_info { | 1047 | struct iwl_rate_info { |
@@ -1502,6 +1516,7 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff); | |||
1502 | void iwl_mvm_tt_exit(struct iwl_mvm *mvm); | 1516 | void iwl_mvm_tt_exit(struct iwl_mvm *mvm); |
1503 | void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state); | 1517 | void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state); |
1504 | int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp); | 1518 | int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp); |
1519 | void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); | ||
1505 | 1520 | ||
1506 | /* Location Aware Regulatory */ | 1521 | /* Location Aware Regulatory */ |
1507 | struct iwl_mcc_update_resp * | 1522 | struct iwl_mcc_update_resp * |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 09a94a5efb61..ecc371e1f3f0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
@@ -263,6 +263,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { | |||
263 | RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif, true), | 263 | RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif, true), |
264 | RX_HANDLER_GRP(PHY_OPS_GROUP, DTS_MEASUREMENT_NOTIF_WIDE, | 264 | RX_HANDLER_GRP(PHY_OPS_GROUP, DTS_MEASUREMENT_NOTIF_WIDE, |
265 | iwl_mvm_temp_notif, true), | 265 | iwl_mvm_temp_notif, true), |
266 | RX_HANDLER_GRP(PHY_OPS_GROUP, CT_KILL_NOTIFICATION, | ||
267 | iwl_mvm_ct_kill_notif, false), | ||
266 | 268 | ||
267 | RX_HANDLER(TDLS_CHANNEL_SWITCH_NOTIFICATION, iwl_mvm_rx_tdls_notif, | 269 | RX_HANDLER(TDLS_CHANNEL_SWITCH_NOTIFICATION, iwl_mvm_rx_tdls_notif, |
268 | true), | 270 | true), |
@@ -387,6 +389,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { | |||
387 | */ | 389 | */ |
388 | static const struct iwl_hcmd_names iwl_mvm_phy_names[] = { | 390 | static const struct iwl_hcmd_names iwl_mvm_phy_names[] = { |
389 | HCMD_NAME(CMD_DTS_MEASUREMENT_TRIGGER_WIDE), | 391 | HCMD_NAME(CMD_DTS_MEASUREMENT_TRIGGER_WIDE), |
392 | HCMD_NAME(CT_KILL_NOTIFICATION), | ||
390 | HCMD_NAME(DTS_MEASUREMENT_NOTIF_WIDE), | 393 | HCMD_NAME(DTS_MEASUREMENT_NOTIF_WIDE), |
391 | }; | 394 | }; |
392 | 395 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index 758d05a8c6aa..6ba391099d7e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH |
10 | * Copyright(c) 2015 - 2016 Intel Deutschland GmbH | ||
10 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of version 2 of the GNU General Public License as | 13 | * it under the terms of version 2 of the GNU General Public License as |
@@ -33,7 +34,7 @@ | |||
33 | * | 34 | * |
34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 35 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | 36 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH |
36 | * Copyright(c) 2015 Intel Deutschland GmbH | 37 | * Copyright(c) 2015 - 2016 Intel Deutschland GmbH |
37 | * All rights reserved. | 38 | * All rights reserved. |
38 | * | 39 | * |
39 | * Redistribution and use in source and binary forms, with or without | 40 | * Redistribution and use in source and binary forms, with or without |
@@ -171,6 +172,24 @@ void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) | |||
171 | iwl_mvm_tt_temp_changed(mvm, temp); | 172 | iwl_mvm_tt_temp_changed(mvm, temp); |
172 | } | 173 | } |
173 | 174 | ||
175 | void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) | ||
176 | { | ||
177 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
178 | struct ct_kill_notif *notif; | ||
179 | int len = iwl_rx_packet_payload_len(pkt); | ||
180 | |||
181 | if (WARN_ON_ONCE(len != sizeof(*notif))) { | ||
182 | IWL_ERR(mvm, "Invalid CT_KILL_NOTIFICATION\n"); | ||
183 | return; | ||
184 | } | ||
185 | |||
186 | notif = (struct ct_kill_notif *)pkt->data; | ||
187 | IWL_DEBUG_TEMP(mvm, "CT Kill notification temperature = %d\n", | ||
188 | notif->temperature); | ||
189 | |||
190 | iwl_mvm_enter_ctkill(mvm); | ||
191 | } | ||
192 | |||
174 | static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm) | 193 | static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm) |
175 | { | 194 | { |
176 | struct iwl_dts_measurement_cmd cmd = { | 195 | struct iwl_dts_measurement_cmd cmd = { |
@@ -236,6 +255,12 @@ static void check_exit_ctkill(struct work_struct *work) | |||
236 | tt = container_of(work, struct iwl_mvm_tt_mgmt, ct_kill_exit.work); | 255 | tt = container_of(work, struct iwl_mvm_tt_mgmt, ct_kill_exit.work); |
237 | mvm = container_of(tt, struct iwl_mvm, thermal_throttle); | 256 | mvm = container_of(tt, struct iwl_mvm, thermal_throttle); |
238 | 257 | ||
258 | if (iwl_mvm_is_tt_in_fw(mvm)) { | ||
259 | iwl_mvm_exit_ctkill(mvm); | ||
260 | |||
261 | return; | ||
262 | } | ||
263 | |||
239 | duration = tt->params.ct_kill_duration; | 264 | duration = tt->params.ct_kill_duration; |
240 | 265 | ||
241 | mutex_lock(&mvm->mutex); | 266 | mutex_lock(&mvm->mutex); |