diff options
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/dvm/main.c | 3 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-io.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h | 24 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 5 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 11 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 2 |
7 files changed, 32 insertions, 17 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 769b75c3fa5b..2c4363662efd 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -1942,7 +1942,8 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) } } -static void iwl_nic_error(struct iwl_op_mode *op_mode, bool sync) +static void iwl_nic_error(struct iwl_op_mode *op_mode, + enum iwl_fw_error_type type) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c index 060becfd64f3..0653ca8b974a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c @@ -526,5 +526,5 @@ void iwl_trans_sync_nmi_with_addr(struct iwl_trans *trans, u32 inta_addr, if (interrupts_enabled) iwl_trans_interrupts(trans, true); - iwl_trans_fw_error(trans, false); + iwl_trans_fw_error(trans, IWL_ERR_TYPE_NMI_FORCED); } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h index 8ef5ed2db051..8febc949b610 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h @@ -45,6 +45,20 @@ struct iwl_cfg; */ /** + * enum iwl_fw_error_type - FW error types/sources + * @IWL_ERR_TYPE_IRQ: "normal" FW error through an IRQ + * @IWL_ERR_TYPE_NMI_FORCED: NMI was forced by driver + * @IWL_ERR_TYPE_RESET_HS_TIMEOUT: reset handshake timed out, + * any debug collection must happen synchronously as + * the device will be shut down + */ +enum iwl_fw_error_type { + IWL_ERR_TYPE_IRQ, + IWL_ERR_TYPE_NMI_FORCED, + IWL_ERR_TYPE_RESET_HS_TIMEOUT, +}; + +/** * struct iwl_op_mode_ops - op_mode specific operations * * The op_mode exports its ops so that external components can start it and @@ -78,7 +92,7 @@ struct iwl_cfg; * there are Tx packets pending in the transport layer. * Must be atomic * @nic_error: error notification. Must be atomic and must be called with BH - * disabled, unless the sync parameter is true. + * disabled, unless the type is IWL_ERR_TYPE_RESET_HS_TIMEOUT * @cmd_queue_full: Called when the command queue gets full. Must be atomic and * called with BH disabled. * @nic_config: configure NIC, called before firmware is started. @@ -104,7 +118,8 @@ struct iwl_op_mode_ops { void (*queue_not_full)(struct iwl_op_mode *op_mode, int queue); bool (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state); void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb); - void (*nic_error)(struct iwl_op_mode *op_mode, bool sync); + void (*nic_error)(struct iwl_op_mode *op_mode, + enum iwl_fw_error_type type); void (*cmd_queue_full)(struct iwl_op_mode *op_mode); void (*nic_config)(struct iwl_op_mode *op_mode); void (*wimax_active)(struct iwl_op_mode *op_mode); @@ -177,9 +192,10 @@ static inline void iwl_op_mode_free_skb(struct iwl_op_mode *op_mode, op_mode->ops->free_skb(op_mode, skb); } -static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode, bool sync) +static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode, + enum iwl_fw_error_type type) { - op_mode->ops->nic_error(op_mode, sync); + op_mode->ops->nic_error(op_mode, type); } static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index c70da7281551..56b551fd2156 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -1120,7 +1120,8 @@ bool _iwl_trans_grab_nic_access(struct iwl_trans *trans); void __releases(nic_access) iwl_trans_release_nic_access(struct iwl_trans *trans); -static inline void iwl_trans_fw_error(struct iwl_trans *trans, bool sync) +static inline void iwl_trans_fw_error(struct iwl_trans *trans, + enum iwl_fw_error_type type) { if (WARN_ON_ONCE(!trans->op_mode)) return; @@ -1128,7 +1129,7 @@ static inline void iwl_trans_fw_error(struct iwl_trans *trans, bool sync) /* prevent double restarts due to the same erroneous FW */ if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status)) { trans->state = IWL_TRANS_NO_FW; - iwl_op_mode_nic_error(trans->op_mode, sync); + iwl_op_mode_nic_error(trans->op_mode, type); } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 0deaf6ed8994..e21199313278 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -2108,7 +2108,8 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) } } -static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode, bool sync) +static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode, + enum iwl_fw_error_type type) { struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); @@ -2117,13 +2118,9 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode, bool sync) &mvm->status)) iwl_mvm_dump_nic_error_log(mvm); - if (sync) { + /* reset HS timeout is during shutdown, so collect right now */ + if (type == IWL_ERR_TYPE_RESET_HS_TIMEOUT) { iwl_fw_error_collect(&mvm->fwrt, true); - /* - * Currently, the only case for sync=true is during - * shutdown, so just stop in this case. If/when that - * changes, we need to be a bit smarter here. - */ return; } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index afb88eab8174..02fef6baf2e3 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1702,7 +1702,7 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) /* The STATUS_FW_ERROR bit is set in this function. This must happen * before we wake up the command caller, to ensure a proper cleanup. */ - iwl_trans_fw_error(trans, false); + iwl_trans_fw_error(trans, IWL_ERR_TYPE_IRQ); clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); wake_up(&trans->wait_command_queue); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 8903a5692dfb..469ef32a3e26 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -124,7 +124,7 @@ static void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans) inta_hw); if (!(inta_hw & MSIX_HW_INT_CAUSES_REG_RESET_DONE)) - iwl_trans_fw_error(trans, true); + iwl_trans_fw_error(trans, IWL_ERR_TYPE_RESET_HS_TIMEOUT); } trans_pcie->fw_reset_state = FW_RESET_IDLE; |
