kfree(drv->fw.dbg_dest_tlv);
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++)
kfree(drv->fw.dbg_conf_tlv[i]);
+ for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++)
+ kfree(drv->fw.dbg_trigger_tlv[i]);
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
iwl_free_fw_img(drv, drv->fw.img + i);
/* FW debug data parsed for driver usage */
struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
- struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
- size_t dbg_conf_tlv_len[FW_DBG_MAX];
+ struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
+ size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
+ struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
+ size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
};
/*
pieces->dbg_conf_tlv_len[conf->id] = tlv_len;
break;
}
+ case IWL_UCODE_TLV_FW_DBG_TRIGGER: {
+ struct iwl_fw_dbg_trigger_tlv *trigger =
+ (void *)tlv_data;
+ u32 trigger_id = le32_to_cpu(trigger->id);
+
+ if (trigger_id >= ARRAY_SIZE(drv->fw.dbg_trigger_tlv)) {
+ IWL_ERR(drv,
+ "Skip unknown trigger: %u\n",
+ trigger->id);
+ break;
+ }
+
+ if (pieces->dbg_trigger_tlv[trigger_id]) {
+ IWL_ERR(drv,
+ "Ignore duplicate dbg trigger %u\n",
+ trigger->id);
+ break;
+ }
+
+ IWL_INFO(drv, "Found debug trigger: %u\n", trigger->id);
+
+ pieces->dbg_trigger_tlv[trigger_id] = trigger;
+ pieces->dbg_trigger_tlv_len[trigger_id] = tlv_len;
+ break;
+ }
case IWL_UCODE_TLV_SEC_RT_USNIFFER:
usniffer_images = true;
iwl_store_ucode_sec(pieces, tlv_data,
}
}
+ for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) {
+ if (pieces->dbg_trigger_tlv[i]) {
+ drv->fw.dbg_trigger_tlv_len[i] =
+ pieces->dbg_trigger_tlv_len[i];
+ drv->fw.dbg_trigger_tlv[i] =
+ kmemdup(pieces->dbg_trigger_tlv[i],
+ drv->fw.dbg_trigger_tlv_len[i],
+ GFP_KERNEL);
+ if (!drv->fw.dbg_trigger_tlv[i])
+ goto out_free_fw;
+ }
+ }
+
/* Now that we can no longer fail, copy information */
/*