Skip to content

Commit

Permalink
iwlwifi: dbg: allow dump collection in case of an early error
Browse files Browse the repository at this point in the history
Improve the robustness of the dump collection flow in case of an early
error:
1. in iwl_trans_pcie_sync_nmi, disable and enable interrupts only if
   they were already enabled
2. attempt to initiate dump collection in iwl_fw_dbg_error_collect only
   if the device is enabled
3. check Tx command queue was already allocated before trying to collect it

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
  • Loading branch information
Shahar S Matityahu authored and Luca Coelho committed Jun 29, 2019
1 parent 9ae3b87 commit e4eee94
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
7 changes: 5 additions & 2 deletions drivers/net/wireless/intel/iwlwifi/fw/dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2057,9 +2057,12 @@ int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
enum iwl_fw_dbg_trigger trig_type)
{
int ret;
struct iwl_fw_dump_desc *iwl_dump_error_desc =
kmalloc(sizeof(*iwl_dump_error_desc), GFP_KERNEL);
struct iwl_fw_dump_desc *iwl_dump_error_desc;

if (!test_bit(STATUS_DEVICE_ENABLED, &fwrt->trans->status))
return -EIO;

iwl_dump_error_desc = kmalloc(sizeof(*iwl_dump_error_desc), GFP_KERNEL);
if (!iwl_dump_error_desc)
return -ENOMEM;

Expand Down
21 changes: 17 additions & 4 deletions drivers/net/wireless/intel/iwlwifi/pcie/trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -3192,7 +3192,7 @@ static struct iwl_trans_dump_data
len = sizeof(*dump_data);

/* host commands */
if (dump_mask & BIT(IWL_FW_ERROR_DUMP_TXCMD))
if (dump_mask & BIT(IWL_FW_ERROR_DUMP_TXCMD) && cmdq)
len += sizeof(*data) +
cmdq->n_window * (sizeof(*txcmd) +
TFD_MAX_PAYLOAD_SIZE);
Expand Down Expand Up @@ -3244,7 +3244,7 @@ static struct iwl_trans_dump_data
len = 0;
data = (void *)dump_data->data;

if (dump_mask & BIT(IWL_FW_ERROR_DUMP_TXCMD)) {
if (dump_mask & BIT(IWL_FW_ERROR_DUMP_TXCMD) && cmdq) {
u16 tfd_size = trans_pcie->tfd_size;

data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_TXCMD);
Expand Down Expand Up @@ -3681,6 +3681,7 @@ void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
bool interrupts_enabled = test_bit(STATUS_INT_ENABLED, &trans->status);
u32 inta_addr, sw_err_bit;

if (trans_pcie->msix_enabled) {
Expand All @@ -3691,7 +3692,12 @@ void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
sw_err_bit = CSR_INT_BIT_SW_ERR;
}

iwl_disable_interrupts(trans);
/* if the interrupts were already disabled, there is no point in
* calling iwl_disable_interrupts
*/
if (interrupts_enabled)
iwl_disable_interrupts(trans);

iwl_force_nmi(trans);
while (time_after(timeout, jiffies)) {
u32 inta_hw = iwl_read32(trans, inta_addr);
Expand All @@ -3705,6 +3711,13 @@ void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)

mdelay(1);
}
iwl_enable_interrupts(trans);

/* enable interrupts only if there were already enabled before this
* function to avoid a case were the driver enable interrupts before
* proper configurations were made
*/
if (interrupts_enabled)
iwl_enable_interrupts(trans);

iwl_trans_fw_error(trans);
}

0 comments on commit e4eee94

Please sign in to comment.