dump->version = cpu_to_le32(IWL_INI_DUMP_VER);
        dump->trigger_id = trigger->trigger_id;
        dump->is_external_cfg =
-               cpu_to_le32(fwrt->trans->dbg.external_ini_loaded);
+               cpu_to_le32(fwrt->trans->dbg.external_ini_cfg);
 
        dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type);
        dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype);
 void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
                            enum iwl_fw_ini_apply_point apply_point)
 {
-       void *data = &fwrt->trans->dbg.apply_points[apply_point];
+       void *data;
 
        IWL_DEBUG_FW(fwrt, "WRT: enabling apply point %d\n", apply_point);
 
        if (apply_point == IWL_FW_INI_APPLY_EARLY)
                iwl_fw_dbg_ini_reset_cfg(fwrt);
 
-       _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
+       if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
+               data = &fwrt->trans->dbg.apply_points[apply_point];
+               _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
+       }
 
-       data = &fwrt->trans->dbg.apply_points_ext[apply_point];
-       _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
+       if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) {
+               data = &fwrt->trans->dbg.apply_points_ext[apply_point];
+               _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
+       }
 }
 IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point);
 
 
 #include "iwl-trans.h"
 #include "iwl-dbg-tlv.h"
 
-void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
-                     bool ext)
+/**
+ * enum iwl_dbg_tlv_type - debug TLV types
+ * @IWL_DBG_TLV_TYPE_DEBUG_INFO: debug info TLV
+ * @IWL_DBG_TLV_TYPE_BUF_ALLOC: buffer allocation TLV
+ * @IWL_DBG_TLV_TYPE_HCMD: host command TLV
+ * @IWL_DBG_TLV_TYPE_REGION: region TLV
+ * @IWL_DBG_TLV_TYPE_TRIGGER: trigger TLV
+ * @IWL_DBG_TLV_TYPE_NUM: number of debug TLVs
+ */
+enum iwl_dbg_tlv_type {
+       IWL_DBG_TLV_TYPE_DEBUG_INFO =
+               IWL_UCODE_TLV_TYPE_DEBUG_INFO - IWL_UCODE_TLV_DEBUG_BASE,
+       IWL_DBG_TLV_TYPE_BUF_ALLOC,
+       IWL_DBG_TLV_TYPE_HCMD,
+       IWL_DBG_TLV_TYPE_REGION,
+       IWL_DBG_TLV_TYPE_TRIGGER,
+       IWL_DBG_TLV_TYPE_NUM,
+};
+
+/**
+ * struct iwl_dbg_tlv_ver_data -  debug TLV version struct
+ * @min_ver: min version supported
+ * @max_ver: max version supported
+ */
+struct iwl_dbg_tlv_ver_data {
+       int min_ver;
+       int max_ver;
+};
+
+static const struct iwl_dbg_tlv_ver_data
+dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = {
+       [IWL_DBG_TLV_TYPE_DEBUG_INFO]   = {.min_ver = 1, .max_ver = 1,},
+       [IWL_DBG_TLV_TYPE_BUF_ALLOC]    = {.min_ver = 1, .max_ver = 1,},
+       [IWL_DBG_TLV_TYPE_HCMD]         = {.min_ver = 1, .max_ver = 1,},
+       [IWL_DBG_TLV_TYPE_REGION]       = {.min_ver = 1, .max_ver = 1,},
+       [IWL_DBG_TLV_TYPE_TRIGGER]      = {.min_ver = 1, .max_ver = 1,},
+};
+
+static int iwl_dbg_tlv_copy(struct iwl_ucode_tlv *tlv, struct list_head *list)
 {
-       struct iwl_apply_point_data *dbg_cfg, *tlv_copy;
-       struct iwl_fw_ini_header *header = (void *)&tlv->data[0];
-       u32 tlv_type = le32_to_cpu(tlv->type);
+       struct iwl_apply_point_data *tlv_copy;
        u32 len = le32_to_cpu(tlv->length);
-       u32 apply_point = le32_to_cpu(header->apply_point);
 
-       if (le32_to_cpu(header->tlv_version) != 1)
-               return;
+       tlv_copy = kzalloc(sizeof(*tlv_copy) + len, GFP_KERNEL);
+       if (!tlv_copy)
+               return -ENOMEM;
 
-       if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
-                     "Invalid apply point %d\n", apply_point))
-               return;
+       INIT_LIST_HEAD(&tlv_copy->list);
+       memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len);
+
+       if (!list->next)
+               INIT_LIST_HEAD(list);
+
+       list_add_tail(&tlv_copy->list, list);
+
+       return 0;
+}
+
+static bool iwl_dbg_tlv_ver_support(struct iwl_ucode_tlv *tlv)
+{
+       struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0];
+       u32 type = le32_to_cpu(tlv->type);
+       u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
+       u32 ver = le32_to_cpu(hdr->tlv_version);
+
+       if (ver < dbg_ver_table[tlv_idx].min_ver ||
+           ver > dbg_ver_table[tlv_idx].max_ver)
+               return false;
+
+       return true;
+}
+
+void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
+                      bool ext)
+{
+       struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0];
+       u32 type = le32_to_cpu(tlv->type);
+       u32 pnt = le32_to_cpu(hdr->apply_point);
+       u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
+       enum iwl_ini_cfg_state *cfg_state = ext ?
+               &trans->dbg.external_ini_cfg : &trans->dbg.internal_ini_cfg;
+       struct list_head *dbg_cfg_list = ext ?
+               &trans->dbg.apply_points_ext[pnt].list :
+               &trans->dbg.apply_points[pnt].list;
 
        IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
-                    tlv_type, apply_point);
+                    type, pnt);
 
-       if (ext)
-               dbg_cfg = &trans->dbg.apply_points_ext[apply_point];
-       else
-               dbg_cfg = &trans->dbg.apply_points[apply_point];
+       if (tlv_idx >= IWL_DBG_TLV_TYPE_NUM) {
+               IWL_ERR(trans, "WRT: Unsupported TLV 0x%x\n", type);
+               goto out_err;
+       }
 
-       tlv_copy = kzalloc(sizeof(*tlv_copy) + len, GFP_KERNEL);
-       if (!tlv_copy) {
-               IWL_ERR(trans, "WRT: No memory for TLV 0x%x, apply point %d\n",
-                       tlv_type, apply_point);
-               return;
+       if (pnt >= IWL_FW_INI_APPLY_NUM) {
+               IWL_ERR(trans, "WRT: Invalid apply point %d\n", pnt);
+               goto out_err;
        }
 
-       INIT_LIST_HEAD(&tlv_copy->list);
-       memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len);
+       if (!iwl_dbg_tlv_ver_support(tlv)) {
+               IWL_ERR(trans, "WRT: Unsupported TLV 0x%x version %u\n", type,
+                       le32_to_cpu(hdr->tlv_version));
+               goto out_err;
+       }
 
-       if (!dbg_cfg->list.next)
-               INIT_LIST_HEAD(&dbg_cfg->list);
+       if (iwl_dbg_tlv_copy(tlv, dbg_cfg_list)) {
+               IWL_ERR(trans,
+                       "WRT: Failed to allocate TLV 0x%x, apply point %d\n",
+                       type, pnt);
+               goto out_err;
+       }
+
+       if (*cfg_state == IWL_INI_CFG_STATE_NOT_LOADED)
+               *cfg_state = IWL_INI_CFG_STATE_LOADED;
 
-       list_add_tail(&tlv_copy->list, &dbg_cfg->list);
+       return;
 
-       trans->dbg.ini_valid = true;
+out_err:
+       *cfg_state = IWL_INI_CFG_STATE_CORRUPTED;
 }
 
 static void iwl_dbg_tlv_free_list(struct list_head *list)
                                 size_t len)
 {
        struct iwl_ucode_tlv *tlv;
-       enum iwl_ucode_tlv_type tlv_type;
        u32 tlv_len;
 
        while (len >= sizeof(*tlv)) {
                tlv = (void *)data;
 
                tlv_len = le32_to_cpu(tlv->length);
-               tlv_type = le32_to_cpu(tlv->type);
 
                if (len < tlv_len) {
                        IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
                len -= ALIGN(tlv_len, 4);
                data += sizeof(*tlv) + ALIGN(tlv_len, 4);
 
-               switch (tlv_type) {
-               case IWL_UCODE_TLV_TYPE_DEBUG_INFO:
-               case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
-               case IWL_UCODE_TLV_TYPE_HCMD:
-               case IWL_UCODE_TLV_TYPE_REGIONS:
-               case IWL_UCODE_TLV_TYPE_TRIGGERS:
-               case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
-                       iwl_dbg_tlv_copy(trans, tlv, true);
-                       break;
-               default:
-                       WARN_ONCE(1, "Invalid TLV %x\n", tlv_type);
-                       break;
-               }
+               iwl_dbg_tlv_alloc(trans, tlv, true);
        }
 
        return 0;
        const struct firmware *fw;
        int res;
 
-       if (trans->dbg.external_ini_loaded || !iwlwifi_mod_params.enable_ini)
+       if (!iwlwifi_mod_params.enable_ini)
                return;
 
        res = request_firmware(&fw, "iwl-dbg-tlv.ini", dev);
 
        iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size);
 
-       trans->dbg.external_ini_loaded = true;
        release_firmware(fw);
 }
 
        IWL_PLAT_PM_MODE_D3,
 };
 
+/**
+ * enum iwl_ini_cfg_state
+ * @IWL_INI_CFG_STATE_NOT_LOADED: no debug cfg was given
+ * @IWL_INI_CFG_STATE_LOADED: debug cfg was found and loaded
+ * @IWL_INI_CFG_STATE_CORRUPTED: debug cfg was found and some of the TLVs
+ *     are corrupted. The rest of the debug TLVs will still be used
+ */
+enum iwl_ini_cfg_state {
+       IWL_INI_CFG_STATE_NOT_LOADED,
+       IWL_INI_CFG_STATE_LOADED,
+       IWL_INI_CFG_STATE_CORRUPTED,
+};
+
 /* Max time to wait for nmi interrupt */
 #define IWL_TRANS_NMI_TIMEOUT (HZ / 4)
 
  * @umac_error_event_table: addr of umac error table
  * @error_event_table_tlv_status: bitmap that indicates what error table
  *     pointers was recevied via TLV. uses enum &iwl_error_event_table_status
- * @external_ini_loaded: indicates if an external ini cfg was given
- * @ini_valid: indicates if debug ini mode is on
+ * @internal_ini_cfg: internal debug cfg state. Uses &enum iwl_ini_cfg_state
+ * @external_ini_cfg: external debug cfg state. Uses &enum iwl_ini_cfg_state
  * @num_blocks: number of blocks in fw_mon
  * @fw_mon: address of the buffers for firmware monitor
  * @is_alloc: bit i is set if buffer i was allocated
        u32 umac_error_event_table;
        unsigned int error_event_table_tlv_status;
 
-       bool external_ini_loaded;
-       bool ini_valid;
+       enum iwl_ini_cfg_state internal_ini_cfg;
+       enum iwl_ini_cfg_state external_ini_cfg;
 
        struct iwl_apply_point_data apply_points[IWL_FW_INI_APPLY_NUM];
        struct iwl_apply_point_data apply_points_ext[IWL_FW_INI_APPLY_NUM];
 
 static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans)
 {
-       return trans->dbg.ini_valid;
+       return trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED ||
+               trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED;
 }
 
 /*****************************************************