aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatti Gottlieb <matti.gottlieb@intel.com>2015-12-31 11:18:02 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2016-02-01 09:40:17 -0500
commit23ae61282b88873bec2d56c78fea531f8485146c (patch)
tree19635e87c9d1055214f3d972f3c824a59c4f278f
parent4cbb8e50338a2f2453ba399ce52562e0a111fc1f (diff)
iwlwifi: mvm: Do not switch to D3 image on suspend
Currently when the driver is configured with wowlan parameters, and enters D3 mode, the driver switches the FW image to D3, and when it exists suspend, it reloads the D0 image. If the firmware supports the consolidation of the D0 & D3 images there is no need to load the D3 image on suspend, and no need to reload the D0 image on resume. Do not switch images on suspend / resume, for firmwares that support consolidated images. Signed-off-by: Matti Gottlieb <matti.gottlieb@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.h13
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/d3.c70
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/drv.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c11
7 files changed, 70 insertions, 38 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
index 29ea1c6705b4..4db4cb7aa73a 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
@@ -396,7 +396,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
396 iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET, 396 iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
397 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); 397 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
398 398
399 iwl_trans_d3_suspend(priv->trans, false); 399 iwl_trans_d3_suspend(priv->trans, false, true);
400 400
401 goto out; 401 goto out;
402 402
@@ -469,7 +469,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
469 /* we'll clear ctx->vif during iwlagn_prepare_restart() */ 469 /* we'll clear ctx->vif during iwlagn_prepare_restart() */
470 vif = ctx->vif; 470 vif = ctx->vif;
471 471
472 ret = iwl_trans_d3_resume(priv->trans, &d3_status, false); 472 ret = iwl_trans_d3_resume(priv->trans, &d3_status, false, true);
473 if (ret) 473 if (ret)
474 goto out_unlock; 474 goto out_unlock;
475 475
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
index 84f8aeb926c8..2273908ad83a 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
@@ -297,6 +297,7 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
297 * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA), 297 * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA),
298 * which also implies support for the scheduler configuration command 298 * which also implies support for the scheduler configuration command
299 * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching 299 * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching
300 * @IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG: Consolidated D3-D0 image
300 * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command 301 * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command
301 * @IWL_UCODE_TLV_CAPA_DC2DC_SUPPORT: supports DC2DC Command 302 * @IWL_UCODE_TLV_CAPA_DC2DC_SUPPORT: supports DC2DC Command
302 * @IWL_UCODE_TLV_CAPA_CSUM_SUPPORT: supports TCP Checksum Offload 303 * @IWL_UCODE_TLV_CAPA_CSUM_SUPPORT: supports TCP Checksum Offload
@@ -330,6 +331,7 @@ enum iwl_ucode_tlv_capa {
330 IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = (__force iwl_ucode_tlv_capa_t)11, 331 IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = (__force iwl_ucode_tlv_capa_t)11,
331 IWL_UCODE_TLV_CAPA_DQA_SUPPORT = (__force iwl_ucode_tlv_capa_t)12, 332 IWL_UCODE_TLV_CAPA_DQA_SUPPORT = (__force iwl_ucode_tlv_capa_t)12,
332 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = (__force iwl_ucode_tlv_capa_t)13, 333 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = (__force iwl_ucode_tlv_capa_t)13,
334 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG = (__force iwl_ucode_tlv_capa_t)17,
333 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = (__force iwl_ucode_tlv_capa_t)18, 335 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = (__force iwl_ucode_tlv_capa_t)18,
334 IWL_UCODE_TLV_CAPA_DC2DC_CONFIG_SUPPORT = (__force iwl_ucode_tlv_capa_t)19, 336 IWL_UCODE_TLV_CAPA_DC2DC_CONFIG_SUPPORT = (__force iwl_ucode_tlv_capa_t)19,
335 IWL_UCODE_TLV_CAPA_CSUM_SUPPORT = (__force iwl_ucode_tlv_capa_t)21, 337 IWL_UCODE_TLV_CAPA_CSUM_SUPPORT = (__force iwl_ucode_tlv_capa_t)21,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index fe170a3fb1a6..e6a5e99f95e0 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -618,9 +618,9 @@ struct iwl_trans_ops {
618 void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); 618 void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
619 void (*stop_device)(struct iwl_trans *trans, bool low_power); 619 void (*stop_device)(struct iwl_trans *trans, bool low_power);
620 620
621 void (*d3_suspend)(struct iwl_trans *trans, bool test); 621 void (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset);
622 int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status, 622 int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status,
623 bool test); 623 bool test, bool reset);
624 624
625 int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); 625 int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
626 626
@@ -925,22 +925,23 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans)
925 _iwl_trans_stop_device(trans, true); 925 _iwl_trans_stop_device(trans, true);
926} 926}
927 927
928static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test) 928static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test,
929 bool reset)
929{ 930{
930 might_sleep(); 931 might_sleep();
931 if (trans->ops->d3_suspend) 932 if (trans->ops->d3_suspend)
932 trans->ops->d3_suspend(trans, test); 933 trans->ops->d3_suspend(trans, test, reset);
933} 934}
934 935
935static inline int iwl_trans_d3_resume(struct iwl_trans *trans, 936static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
936 enum iwl_d3_status *status, 937 enum iwl_d3_status *status,
937 bool test) 938 bool test, bool reset)
938{ 939{
939 might_sleep(); 940 might_sleep();
940 if (!trans->ops->d3_resume) 941 if (!trans->ops->d3_resume)
941 return 0; 942 return 0;
942 943
943 return trans->ops->d3_resume(trans, status, test); 944 return trans->ops->d3_resume(trans, status, test, reset);
944} 945}
945 946
946static inline void iwl_trans_ref(struct iwl_trans *trans) 947static inline void iwl_trans_ref(struct iwl_trans *trans)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index d3e21d95cece..78572ef89b26 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -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
@@ -1023,14 +1025,18 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
1023 struct ieee80211_sta *ap_sta) 1025 struct ieee80211_sta *ap_sta)
1024{ 1026{
1025 int ret; 1027 int ret;
1028 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
1029 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
1026 1030
1027 ret = iwl_mvm_switch_to_d3(mvm); 1031 if (!unified_image) {
1028 if (ret) 1032 ret = iwl_mvm_switch_to_d3(mvm);
1029 return ret; 1033 if (ret)
1034 return ret;
1030 1035
1031 ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta); 1036 ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta);
1032 if (ret) 1037 if (ret)
1033 return ret; 1038 return ret;
1039 }
1034 1040
1035 if (!iwlwifi_mod_params.sw_crypto) { 1041 if (!iwlwifi_mod_params.sw_crypto) {
1036 /* 1042 /*
@@ -1072,10 +1078,14 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
1072{ 1078{
1073 struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; 1079 struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
1074 int ret; 1080 int ret;
1081 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
1082 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
1075 1083
1076 ret = iwl_mvm_switch_to_d3(mvm); 1084 if (!unified_image) {
1077 if (ret) 1085 ret = iwl_mvm_switch_to_d3(mvm);
1078 return ret; 1086 if (ret)
1087 return ret;
1088 }
1079 1089
1080 /* rfkill release can be either for wowlan or netdetect */ 1090 /* rfkill release can be either for wowlan or netdetect */
1081 if (wowlan->rfkill_release) 1091 if (wowlan->rfkill_release)
@@ -1151,6 +1161,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1151 }; 1161 };
1152 int ret; 1162 int ret;
1153 int len __maybe_unused; 1163 int len __maybe_unused;
1164 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
1165 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
1154 1166
1155 if (!wowlan) { 1167 if (!wowlan) {
1156 /* 1168 /*
@@ -1236,7 +1248,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1236 1248
1237 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 1249 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1238 1250
1239 iwl_trans_d3_suspend(mvm->trans, test); 1251 iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
1240 out: 1252 out:
1241 if (ret < 0) { 1253 if (ret < 0) {
1242 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); 1254 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
@@ -1299,7 +1311,7 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1299 __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags); 1311 __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
1300 mutex_unlock(&mvm->d0i3_suspend_mutex); 1312 mutex_unlock(&mvm->d0i3_suspend_mutex);
1301 1313
1302 iwl_trans_d3_suspend(trans, false); 1314 iwl_trans_d3_suspend(trans, false, false);
1303 1315
1304 return 0; 1316 return 0;
1305 } 1317 }
@@ -2041,9 +2053,14 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
2041static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) 2053static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
2042{ 2054{
2043 struct ieee80211_vif *vif = NULL; 2055 struct ieee80211_vif *vif = NULL;
2044 int ret; 2056 int ret = 1;
2045 enum iwl_d3_status d3_status; 2057 enum iwl_d3_status d3_status;
2046 bool keep = false; 2058 bool keep = false;
2059 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
2060 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
2061
2062 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE |
2063 CMD_WAKE_UP_TRANS;
2047 2064
2048 mutex_lock(&mvm->mutex); 2065 mutex_lock(&mvm->mutex);
2049 2066
@@ -2052,7 +2069,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
2052 if (IS_ERR_OR_NULL(vif)) 2069 if (IS_ERR_OR_NULL(vif))
2053 goto err; 2070 goto err;
2054 2071
2055 ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test); 2072 ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image);
2056 if (ret) 2073 if (ret)
2057 goto err; 2074 goto err;
2058 2075
@@ -2095,17 +2112,28 @@ out_iterate:
2095 iwl_mvm_d3_disconnect_iter, keep ? vif : NULL); 2112 iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
2096 2113
2097out: 2114out:
2098 /* return 1 to reconfigure the device */ 2115 if (unified_image && !ret) {
2116 ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL);
2117 if (!ret) /* D3 ended successfully - no need to reset device */
2118 return 0;
2119 }
2120
2121 /*
2122 * Reconfigure the device in one of the following cases:
2123 * 1. We are not using a unified image
2124 * 2. We are using a unified image but had an error while exiting D3
2125 */
2099 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 2126 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
2100 set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status); 2127 set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
2101 2128 /*
2102 /* We always return 1, which causes mac80211 to do a reconfig 2129 * When switching images we return 1, which causes mac80211
2103 * with IEEE80211_RECONFIG_TYPE_RESTART. This type of 2130 * to do a reconfig with IEEE80211_RECONFIG_TYPE_RESTART.
2104 * reconfig calls iwl_mvm_restart_complete(), where we unref 2131 * This type of reconfig calls iwl_mvm_restart_complete(),
2105 * the IWL_MVM_REF_UCODE_DOWN, so we need to take the 2132 * where we unref the IWL_MVM_REF_UCODE_DOWN, so we need
2106 * reference here. 2133 * to take the reference here.
2107 */ 2134 */
2108 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); 2135 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
2136
2109 return 1; 2137 return 1;
2110} 2138}
2111 2139
@@ -2122,7 +2150,7 @@ static int iwl_mvm_resume_d0i3(struct iwl_mvm *mvm)
2122 enum iwl_d3_status d3_status; 2150 enum iwl_d3_status d3_status;
2123 struct iwl_trans *trans = mvm->trans; 2151 struct iwl_trans *trans = mvm->trans;
2124 2152
2125 iwl_trans_d3_resume(trans, &d3_status, false); 2153 iwl_trans_d3_resume(trans, &d3_status, false, false);
2126 2154
2127 /* 2155 /*
2128 * make sure to clear D0I3_DEFER_WAKEUP before 2156 * make sure to clear D0I3_DEFER_WAKEUP before
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 9a15642f80dd..0476e7688e9b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -1109,7 +1109,7 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1109 cmd->general_flags = cpu_to_le32(iwl_mvm_scan_umac_flags(mvm, params, 1109 cmd->general_flags = cpu_to_le32(iwl_mvm_scan_umac_flags(mvm, params,
1110 vif)); 1110 vif));
1111 1111
1112 if (type == IWL_MVM_SCAN_SCHED) 1112 if (type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT)
1113 cmd->flags = cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE); 1113 cmd->flags = cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE);
1114 1114
1115 if (iwl_mvm_scan_use_ebs(mvm, vif)) 1115 if (iwl_mvm_scan_use_ebs(mvm, vif))
@@ -1351,7 +1351,7 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
1351 1351
1352 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) { 1352 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
1353 hcmd.id = iwl_cmd_id(SCAN_REQ_UMAC, IWL_ALWAYS_LONG_GROUP, 0); 1353 hcmd.id = iwl_cmd_id(SCAN_REQ_UMAC, IWL_ALWAYS_LONG_GROUP, 0);
1354 ret = iwl_mvm_scan_umac(mvm, vif, &params, IWL_MVM_SCAN_SCHED); 1354 ret = iwl_mvm_scan_umac(mvm, vif, &params, type);
1355 } else { 1355 } else {
1356 hcmd.id = SCAN_OFFLOAD_REQUEST_CMD; 1356 hcmd.id = SCAN_OFFLOAD_REQUEST_CMD;
1357 ret = iwl_mvm_scan_lmac(mvm, vif, &params); 1357 ret = iwl_mvm_scan_lmac(mvm, vif, &params);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 16b579a5aa6b..762e7c4d96b6 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -787,7 +787,7 @@ static int iwl_pci_runtime_suspend(struct device *device)
787 787
788 trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3; 788 trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3;
789 789
790 iwl_trans_d3_suspend(trans, false); 790 iwl_trans_d3_suspend(trans, false, false);
791 791
792 return 0; 792 return 0;
793} 793}
@@ -800,7 +800,7 @@ static int iwl_pci_runtime_resume(struct device *device)
800 800
801 IWL_DEBUG_RPM(trans, "exiting runtime suspend (resume)\n"); 801 IWL_DEBUG_RPM(trans, "exiting runtime suspend (resume)\n");
802 802
803 iwl_trans_d3_resume(trans, &d3_status, false); 803 iwl_trans_d3_resume(trans, &d3_status, false, false);
804 804
805 if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) 805 if (test_bit(STATUS_DEVICE_ENABLED, &trans->status))
806 return iwl_pci_fw_exit_d0i3(trans); 806 return iwl_pci_fw_exit_d0i3(trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index cfdc7f6e554a..abe091698471 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1219,11 +1219,12 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state)
1219 _iwl_trans_pcie_stop_device(trans, true); 1219 _iwl_trans_pcie_stop_device(trans, true);
1220} 1220}
1221 1221
1222static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test) 1222static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
1223 bool reset)
1223{ 1224{
1224 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1225 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1225 1226
1226 if (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3) { 1227 if (!reset) {
1227 /* Enable persistence mode to avoid reset */ 1228 /* Enable persistence mode to avoid reset */
1228 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, 1229 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
1229 CSR_HW_IF_CONFIG_REG_PERSIST_MODE); 1230 CSR_HW_IF_CONFIG_REG_PERSIST_MODE);
@@ -1247,7 +1248,7 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test)
1247 iwl_clear_bit(trans, CSR_GP_CNTRL, 1248 iwl_clear_bit(trans, CSR_GP_CNTRL,
1248 CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 1249 CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
1249 1250
1250 if (trans->system_pm_mode == IWL_PLAT_PM_MODE_D3) { 1251 if (reset) {
1251 /* 1252 /*
1252 * reset TX queues -- some of their registers reset during S3 1253 * reset TX queues -- some of their registers reset during S3
1253 * so if we don't reset everything here the D3 image would try 1254 * so if we don't reset everything here the D3 image would try
@@ -1261,7 +1262,7 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test)
1261 1262
1262static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, 1263static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
1263 enum iwl_d3_status *status, 1264 enum iwl_d3_status *status,
1264 bool test) 1265 bool test, bool reset)
1265{ 1266{
1266 u32 val; 1267 u32 val;
1267 int ret; 1268 int ret;
@@ -1296,7 +1297,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
1296 1297
1297 iwl_pcie_set_pwr(trans, false); 1298 iwl_pcie_set_pwr(trans, false);
1298 1299
1299 if (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3) { 1300 if (!reset) {
1300 iwl_clear_bit(trans, CSR_GP_CNTRL, 1301 iwl_clear_bit(trans, CSR_GP_CNTRL,
1301 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1302 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1302 } else { 1303 } else {