Skip to content

Commit

Permalink
iwlwifi: mvm: fix firmware debug restart recording
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Emmanuel Grumbach authored and Luca Coelho committed Jun 5, 2017
1 parent d995440 commit addce85
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 19 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/intel/iwlwifi/iwl-prph.h
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@
#define MON_DMARB_RD_DATA_ADDR (0xa03c5c)

#define DBGC_IN_SAMPLE (0xa03c00)
#define DBGC_OUT_CTRL (0xa03c0c)

/* enable the ID buf for read */
#define WFPM_PS_CTL_CLR 0xA0300C
Expand Down
12 changes: 1 addition & 11 deletions drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1002,14 +1002,6 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
return 0;
}

static inline void iwl_mvm_restart_early_start(struct iwl_mvm *mvm)
{
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
iwl_clear_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
else
iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 1);
}

int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
{
u8 *ptr;
Expand All @@ -1023,10 +1015,8 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
/* EARLY START - firmware's configuration is hard coded */
if ((!mvm->fw->dbg_conf_tlv[conf_id] ||
!mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) &&
conf_id == FW_DBG_START_FROM_ALIVE) {
iwl_mvm_restart_early_start(mvm);
conf_id == FW_DBG_START_FROM_ALIVE)
return 0;
}

if (!mvm->fw->dbg_conf_tlv[conf_id])
return -EINVAL;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1756,6 +1756,7 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
if (!iwl_mvm_has_new_tx_api(mvm))
iwl_free_fw_paging(mvm);
mvm->ucode_loaded = false;
mvm->fw_dbg_conf = FW_DBG_INVALID;
iwl_trans_stop_device(mvm->trans);
}

Expand Down
32 changes: 24 additions & 8 deletions drivers/net/wireless/intel/iwlwifi/mvm/ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1149,21 +1149,37 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)

mutex_lock(&mvm->mutex);

/* stop recording */
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
/* stop recording */
iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);

iwl_mvm_fw_error_dump(mvm);

/* start recording again if the firmware is not crashed */
if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) &&
mvm->fw->dbg_dest_tlv)
iwl_clear_bits_prph(mvm->trans,
MON_BUFF_SAMPLE_CTL, 0x100);
} else {
u32 in_sample = iwl_read_prph(mvm->trans, DBGC_IN_SAMPLE);
u32 out_ctrl = iwl_read_prph(mvm->trans, DBGC_OUT_CTRL);

/* stop recording */
iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
/* wait before we collect the data till the DBGC stop */
udelay(100);
}
iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0);
/* wait before we collect the data till the DBGC stop */
udelay(500);

iwl_mvm_fw_error_dump(mvm);
iwl_mvm_fw_error_dump(mvm);

/* start recording again if the firmware is not crashed */
WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) &&
mvm->fw->dbg_dest_tlv &&
iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
/* start recording again if the firmware is not crashed */
if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) &&
mvm->fw->dbg_dest_tlv) {
iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, in_sample);
iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, out_ctrl);
}
}

mutex_unlock(&mvm->mutex);

Expand Down

0 comments on commit addce85

Please sign in to comment.