* @id: region id. Max id is &IWL_FW_INI_MAX_REGION_ID
  * @type: region type. One of &enum iwl_fw_ini_region_type
  * @sub_type: region sub type
- * @sub_type_ver: region sub type
+ * @sub_type_ver: region sub type version
  * @reserved: not in use
  * @name: region name
  * @dev_addr: device address configuration. Used by
        IWL_FW_INI_APPLY_POLICY_OVERRIDE_CFG            = BIT(9),
        IWL_FW_INI_APPLY_POLICY_OVERRIDE_DATA           = BIT(10),
 };
+
+/**
+ * enum iwl_fw_ini_trigger_reset_fw_policy - Determines how to handle reset
+ *
+ * @IWL_FW_INI_RESET_FW_MODE_NOTHING: do not stop FW and reload (default)
+ * @IWL_FW_INI_RESET_FW_MODE_STOP_FW_ONLY: stop FW without reload FW
+ * @IWL_FW_INI_RESET_FW_MODE_STOP_AND_RELOAD_FW: stop FW with reload FW
+ */
+enum iwl_fw_ini_trigger_reset_fw_policy {
+       IWL_FW_INI_RESET_FW_MODE_NOTHING = 0,
+       IWL_FW_INI_RESET_FW_MODE_STOP_FW_ONLY,
+       IWL_FW_INI_RESET_FW_MODE_STOP_AND_RELOAD_FW
+};
 #endif
 
        const struct iwl_fw_ini_trigger_tlv *trig = (const void *)tlv->data;
        struct iwl_fw_ini_trigger_tlv *dup_trig;
        u32 tp = le32_to_cpu(trig->time_point);
+       u32 rf = le32_to_cpu(trig->reset_fw);
        struct iwl_ucode_tlv *dup = NULL;
        int ret;
 
                return -EINVAL;
        }
 
+       IWL_DEBUG_FW(trans,
+                    "WRT: time point %u for trigger TLV with reset_fw %u\n",
+                    tp, rf);
+       trans->dbg.last_tp_resetfw = 0xFF;
        if (!le32_to_cpu(trig->occurrences)) {
                dup = kmemdup(tlv, sizeof(*tlv) + le32_to_cpu(tlv->length),
                                GFP_KERNEL);
                u32 num_data = iwl_tlv_array_len(&node->tlv, dump_data.trig,
                                                 data);
                int ret, i;
+               u32 tp = le32_to_cpu(dump_data.trig->time_point);
+
 
                if (!num_data) {
                        ret = iwl_fw_dbg_ini_collect(fwrt, &dump_data, sync);
                                break;
                        }
                }
-       }
 
+               fwrt->trans->dbg.restart_required = FALSE;
+               IWL_DEBUG_INFO(fwrt, "WRT: tp %d, reset_fw %d\n",
+                              tp, dump_data.trig->reset_fw);
+               IWL_DEBUG_INFO(fwrt, "WRT: restart_required %d, last_tp_resetfw %d\n",
+                              fwrt->trans->dbg.restart_required,
+                              fwrt->trans->dbg.last_tp_resetfw);
+
+               if (fwrt->trans->trans_cfg->device_family ==
+                   IWL_DEVICE_FAMILY_9000) {
+                       fwrt->trans->dbg.restart_required = TRUE;
+               } else if (tp == IWL_FW_INI_TIME_POINT_FW_ASSERT &&
+                          fwrt->trans->dbg.last_tp_resetfw ==
+                          IWL_FW_INI_RESET_FW_MODE_STOP_FW_ONLY) {
+                       fwrt->trans->dbg.restart_required = FALSE;
+                       fwrt->trans->dbg.last_tp_resetfw = 0xFF;
+                       IWL_DEBUG_FW(fwrt, "WRT: FW_ASSERT due to reset_fw_mode-no restart\n");
+               } else if (le32_to_cpu(dump_data.trig->reset_fw) ==
+                          IWL_FW_INI_RESET_FW_MODE_STOP_AND_RELOAD_FW) {
+                       IWL_DEBUG_INFO(fwrt, "WRT: stop and reload firmware\n");
+                       fwrt->trans->dbg.restart_required = TRUE;
+               } else if (le32_to_cpu(dump_data.trig->reset_fw) ==
+                          IWL_FW_INI_RESET_FW_MODE_STOP_FW_ONLY) {
+                       IWL_DEBUG_INFO(fwrt, "WRT: stop only and no reload firmware\n");
+                       fwrt->trans->dbg.restart_required = FALSE;
+                       fwrt->trans->dbg.last_tp_resetfw =
+                               le32_to_cpu(dump_data.trig->reset_fw);
+               } else if (le32_to_cpu(dump_data.trig->reset_fw) ==
+                          IWL_FW_INI_RESET_FW_MODE_NOTHING) {
+                       IWL_DEBUG_INFO(fwrt,
+                                      "WRT: nothing need to be done after debug collection\n");
+               } else {
+                       IWL_ERR(fwrt, "WRT: wrong resetfw %d\n",
+                               le32_to_cpu(dump_data.trig->reset_fw));
+               }
+       }
        return 0;
 }
 
 
 
                iwl_fw_error_collect(&mvm->fwrt, false);
 
-               if (fw_error && mvm->fw_restart > 0)
+               if (fw_error && mvm->fw_restart > 0) {
                        mvm->fw_restart--;
-               ieee80211_restart_hw(mvm->hw);
+                       ieee80211_restart_hw(mvm->hw);
+               } else if (mvm->fwrt.trans->dbg.restart_required) {
+                       IWL_DEBUG_INFO(mvm, "FW restart requested after debug collection\n");
+                       mvm->fwrt.trans->dbg.restart_required = FALSE;
+                       ieee80211_restart_hw(mvm->hw);
+               } else if (mvm->trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_8000) {
+                       ieee80211_restart_hw(mvm->hw);
+               }
        }
 }
 
        if (!test_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status))
                return;
 
-       iwl_mvm_nic_restart(mvm, true);
+       iwl_mvm_nic_restart(mvm, false);
 }
 
 static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)