aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2017-03-29 03:21:09 -0400
committerLuca Coelho <luciano.coelho@intel.com>2017-06-05 14:47:08 -0400
commitaddce854f164a68da9cb158e2e7e447705068549 (patch)
tree0345ee7ae8d93ff756008b308acb893707bee272
parentd9954405758a0cbbe258d9b4d4dc12a06fa48a28 (diff)
iwlwifi: mvm: fix firmware debug restart recording
When we want to stop the recording of the firmware debug and restart it later without reloading the firmware we don't need to resend the configuration that comes with host commands. Sending those commands confused the hardware and led to an NMI 0x66. Change the flow as following: * read the relevant registers (DBGC_IN_SAMPLE, DBGC_OUT_CTRL) * clear those registers * wait for the hardware to complete its write to the buffer * get the data * restore the value of those registers (to restart the recording) For early start (where the configuration is already compiled in the firmware), we don't need to set those registers after the firmware has been loaded, but only when we want to restart the recording without having restarted the firmware. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-prph.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c32
4 files changed, 27 insertions, 19 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index 306bc967742e..77efbb78e867 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -370,6 +370,7 @@
370#define MON_DMARB_RD_DATA_ADDR (0xa03c5c) 370#define MON_DMARB_RD_DATA_ADDR (0xa03c5c)
371 371
372#define DBGC_IN_SAMPLE (0xa03c00) 372#define DBGC_IN_SAMPLE (0xa03c00)
373#define DBGC_OUT_CTRL (0xa03c0c)
373 374
374/* enable the ID buf for read */ 375/* enable the ID buf for read */
375#define WFPM_PS_CTL_CLR 0xA0300C 376#define WFPM_PS_CTL_CLR 0xA0300C
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
index 7b86a4f1b574..c8712e6eea74 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
@@ -1002,14 +1002,6 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
1002 return 0; 1002 return 0;
1003} 1003}
1004 1004
1005static inline void iwl_mvm_restart_early_start(struct iwl_mvm *mvm)
1006{
1007 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
1008 iwl_clear_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
1009 else
1010 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 1);
1011}
1012
1013int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id) 1005int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
1014{ 1006{
1015 u8 *ptr; 1007 u8 *ptr;
@@ -1023,10 +1015,8 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
1023 /* EARLY START - firmware's configuration is hard coded */ 1015 /* EARLY START - firmware's configuration is hard coded */
1024 if ((!mvm->fw->dbg_conf_tlv[conf_id] || 1016 if ((!mvm->fw->dbg_conf_tlv[conf_id] ||
1025 !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) && 1017 !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) &&
1026 conf_id == FW_DBG_START_FROM_ALIVE) { 1018 conf_id == FW_DBG_START_FROM_ALIVE)
1027 iwl_mvm_restart_early_start(mvm);
1028 return 0; 1019 return 0;
1029 }
1030 1020
1031 if (!mvm->fw->dbg_conf_tlv[conf_id]) 1021 if (!mvm->fw->dbg_conf_tlv[conf_id])
1032 return -EINVAL; 1022 return -EINVAL;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index ed20c0c5abc8..52f8d7a6a7dc 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1756,6 +1756,7 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
1756 if (!iwl_mvm_has_new_tx_api(mvm)) 1756 if (!iwl_mvm_has_new_tx_api(mvm))
1757 iwl_free_fw_paging(mvm); 1757 iwl_free_fw_paging(mvm);
1758 mvm->ucode_loaded = false; 1758 mvm->ucode_loaded = false;
1759 mvm->fw_dbg_conf = FW_DBG_INVALID;
1759 iwl_trans_stop_device(mvm->trans); 1760 iwl_trans_stop_device(mvm->trans);
1760} 1761}
1761 1762
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 9ffff6ed8133..3da5ec40aaea 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1149,21 +1149,37 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
1149 1149
1150 mutex_lock(&mvm->mutex); 1150 mutex_lock(&mvm->mutex);
1151 1151
1152 /* stop recording */
1153 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 1152 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
1153 /* stop recording */
1154 iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); 1154 iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
1155
1156 iwl_mvm_fw_error_dump(mvm);
1157
1158 /* start recording again if the firmware is not crashed */
1159 if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) &&
1160 mvm->fw->dbg_dest_tlv)
1161 iwl_clear_bits_prph(mvm->trans,
1162 MON_BUFF_SAMPLE_CTL, 0x100);
1155 } else { 1163 } else {
1164 u32 in_sample = iwl_read_prph(mvm->trans, DBGC_IN_SAMPLE);
1165 u32 out_ctrl = iwl_read_prph(mvm->trans, DBGC_OUT_CTRL);
1166
1167 /* stop recording */
1156 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); 1168 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
1157 /* wait before we collect the data till the DBGC stop */
1158 udelay(100); 1169 udelay(100);
1159 } 1170 iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0);
1171 /* wait before we collect the data till the DBGC stop */
1172 udelay(500);
1160 1173
1161 iwl_mvm_fw_error_dump(mvm); 1174 iwl_mvm_fw_error_dump(mvm);
1162 1175
1163 /* start recording again if the firmware is not crashed */ 1176 /* start recording again if the firmware is not crashed */
1164 WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) && 1177 if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) &&
1165 mvm->fw->dbg_dest_tlv && 1178 mvm->fw->dbg_dest_tlv) {
1166 iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf)); 1179 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, in_sample);
1180 iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, out_ctrl);
1181 }
1182 }
1167 1183
1168 mutex_unlock(&mvm->mutex); 1184 mutex_unlock(&mvm->mutex);
1169 1185