mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-27 12:45:16 +07:00
iwlwifi: dbg: add apply point logic
Add a function to be called when apply point occurs. For each of the TLVs, the function will perform the apply point logic: - For HCMD - send the stored host command - For buffer allocation - allocate the memory and send the buffer allocation command - For trigger and region - update the stored configuration Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
743742231a
commit
d47902f9f7
@ -1263,3 +1263,210 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)
|
|||||||
cfg->d3_debug_data_length);
|
cfg->d3_debug_data_length);
|
||||||
}
|
}
|
||||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data);
|
IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data);
|
||||||
|
|
||||||
|
static void
|
||||||
|
iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_fw_ini_allocation_tlv *alloc)
|
||||||
|
{
|
||||||
|
struct iwl_trans *trans = fwrt->trans;
|
||||||
|
struct iwl_continuous_record_cmd cont_rec = {};
|
||||||
|
struct iwl_buffer_allocation_cmd *cmd = (void *)&cont_rec.pad[0];
|
||||||
|
struct iwl_host_cmd hcmd = {
|
||||||
|
.id = LDBG_CONFIG_CMD,
|
||||||
|
.flags = CMD_ASYNC,
|
||||||
|
.data[0] = &cont_rec,
|
||||||
|
.len[0] = sizeof(cont_rec),
|
||||||
|
};
|
||||||
|
void *virtual_addr = NULL;
|
||||||
|
u32 size = le32_to_cpu(alloc->size);
|
||||||
|
dma_addr_t phys_addr;
|
||||||
|
|
||||||
|
cont_rec.record_mode.enable_recording = cpu_to_le16(BUFFER_ALLOCATION);
|
||||||
|
|
||||||
|
if (!trans->num_blocks &&
|
||||||
|
le32_to_cpu(alloc->buffer_location) !=
|
||||||
|
IWL_FW_INI_LOCATION_DRAM_PATH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
virtual_addr = dma_alloc_coherent(fwrt->trans->dev, size,
|
||||||
|
&phys_addr, GFP_KERNEL);
|
||||||
|
|
||||||
|
/* TODO: alloc fragments if needed */
|
||||||
|
if (!virtual_addr)
|
||||||
|
IWL_ERR(fwrt, "Failed to allocate debug memory\n");
|
||||||
|
|
||||||
|
if (WARN_ON_ONCE(trans->num_blocks == ARRAY_SIZE(trans->fw_mon)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
trans->fw_mon[trans->num_blocks].block = virtual_addr;
|
||||||
|
trans->fw_mon[trans->num_blocks].physical = phys_addr;
|
||||||
|
trans->fw_mon[trans->num_blocks].size = size;
|
||||||
|
trans->num_blocks++;
|
||||||
|
|
||||||
|
IWL_DEBUG_FW(trans, "Allocated debug block of size %d\n", size);
|
||||||
|
|
||||||
|
/* First block is assigned via registers / context info */
|
||||||
|
if (trans->num_blocks == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cmd->num_frags = cpu_to_le32(1);
|
||||||
|
cmd->fragments[0].address = cpu_to_le64(phys_addr);
|
||||||
|
cmd->fragments[0].size = alloc->size;
|
||||||
|
cmd->allocation_id = alloc->allocation_id;
|
||||||
|
cmd->buffer_location = alloc->buffer_location;
|
||||||
|
|
||||||
|
iwl_trans_send_cmd(trans, &hcmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_ucode_tlv *tlv)
|
||||||
|
{
|
||||||
|
struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)&tlv->data[0];
|
||||||
|
struct iwl_fw_ini_hcmd *data = &hcmd_tlv->hcmd;
|
||||||
|
u16 len = le32_to_cpu(tlv->length) - sizeof(*hcmd_tlv);
|
||||||
|
|
||||||
|
struct iwl_host_cmd hcmd = {
|
||||||
|
.id = WIDE_ID(data->group, data->id),
|
||||||
|
.len = { len, },
|
||||||
|
.data = { data->data, },
|
||||||
|
};
|
||||||
|
|
||||||
|
iwl_trans_send_cmd(fwrt->trans, &hcmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_fw_ini_region_tlv *tlv,
|
||||||
|
bool ext, enum iwl_fw_ini_apply_point pnt)
|
||||||
|
{
|
||||||
|
void *iter = (void *)tlv->region_config;
|
||||||
|
int i, size = le32_to_cpu(tlv->num_regions);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
struct iwl_fw_ini_region_cfg *reg = iter;
|
||||||
|
int id = le32_to_cpu(reg->region_id);
|
||||||
|
struct iwl_fw_ini_active_regs *active;
|
||||||
|
|
||||||
|
if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_regs)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
active = &fwrt->dump.active_regs[id];
|
||||||
|
|
||||||
|
if (ext && active->apply_point == pnt)
|
||||||
|
IWL_WARN(fwrt->trans,
|
||||||
|
"External region TLV overrides FW default %x\n",
|
||||||
|
id);
|
||||||
|
|
||||||
|
IWL_DEBUG_FW(fwrt,
|
||||||
|
"%s: apply point %d, activating region ID %d\n",
|
||||||
|
__func__, pnt, id);
|
||||||
|
|
||||||
|
active->reg = reg;
|
||||||
|
active->apply_point = pnt;
|
||||||
|
|
||||||
|
if (le32_to_cpu(reg->region_type) !=
|
||||||
|
IWL_FW_INI_REGION_DRAM_BUFFER)
|
||||||
|
iter += le32_to_cpu(reg->num_regions) * sizeof(__le32);
|
||||||
|
|
||||||
|
iter += sizeof(*reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_fw_ini_trigger_tlv *tlv,
|
||||||
|
bool ext,
|
||||||
|
enum iwl_fw_ini_apply_point apply_point)
|
||||||
|
{
|
||||||
|
int i, size = le32_to_cpu(tlv->num_triggers);
|
||||||
|
void *iter = (void *)tlv->trigger_config;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
struct iwl_fw_ini_trigger *trig = iter;
|
||||||
|
struct iwl_fw_ini_active_triggers *active;
|
||||||
|
int id = le32_to_cpu(trig->trigger_id);
|
||||||
|
u32 num;
|
||||||
|
|
||||||
|
if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
active = &fwrt->dump.active_trigs[id];
|
||||||
|
|
||||||
|
if (active->apply_point != apply_point) {
|
||||||
|
active->conf = NULL;
|
||||||
|
active->conf_ext = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
num = le32_to_cpu(trig->num_regions);
|
||||||
|
|
||||||
|
if (ext && active->apply_point == apply_point) {
|
||||||
|
num += le32_to_cpu(active->conf->num_regions);
|
||||||
|
if (trig->ignore_default) {
|
||||||
|
active->conf_ext = active->conf;
|
||||||
|
active->conf = trig;
|
||||||
|
} else {
|
||||||
|
active->conf_ext = trig;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
active->conf = trig;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter += sizeof(*trig) +
|
||||||
|
le32_to_cpu(trig->num_regions) * sizeof(__le32);
|
||||||
|
|
||||||
|
active->active = num;
|
||||||
|
active->apply_point = apply_point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_apply_point_data *data,
|
||||||
|
enum iwl_fw_ini_apply_point pnt,
|
||||||
|
bool ext)
|
||||||
|
{
|
||||||
|
void *iter = data->data;
|
||||||
|
|
||||||
|
while (iter && iter < data->data + data->size) {
|
||||||
|
struct iwl_ucode_tlv *tlv = iter;
|
||||||
|
void *ini_tlv = (void *)tlv->data;
|
||||||
|
u32 type = le32_to_cpu(tlv->type);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
|
||||||
|
iwl_fw_dbg_buffer_allocation(fwrt, ini_tlv);
|
||||||
|
break;
|
||||||
|
case IWL_UCODE_TLV_TYPE_HCMD:
|
||||||
|
if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) {
|
||||||
|
IWL_ERR(fwrt,
|
||||||
|
"Invalid apply point %x for host command\n",
|
||||||
|
pnt);
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
iwl_fw_dbg_send_hcmd(fwrt, tlv);
|
||||||
|
break;
|
||||||
|
case IWL_UCODE_TLV_TYPE_REGIONS:
|
||||||
|
iwl_fw_dbg_update_regions(fwrt, ini_tlv, ext, pnt);
|
||||||
|
break;
|
||||||
|
case IWL_UCODE_TLV_TYPE_TRIGGERS:
|
||||||
|
iwl_fw_dbg_update_triggers(fwrt, ini_tlv, ext, pnt);
|
||||||
|
break;
|
||||||
|
case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ONCE(1, "Invalid TLV %x for apply point\n", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next:
|
||||||
|
iter += sizeof(*tlv) + le32_to_cpu(tlv->length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
|
||||||
|
enum iwl_fw_ini_apply_point apply_point)
|
||||||
|
{
|
||||||
|
void *data = &fwrt->trans->apply_points[apply_point];
|
||||||
|
|
||||||
|
_iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
|
||||||
|
|
||||||
|
data = &fwrt->trans->apply_points_ext[apply_point];
|
||||||
|
_iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
|
||||||
|
}
|
||||||
|
IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point);
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "error-dump.h"
|
#include "error-dump.h"
|
||||||
#include "api/commands.h"
|
#include "api/commands.h"
|
||||||
|
#include "api/dbg-tlv.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_fw_dump_desc - describes the dump
|
* struct iwl_fw_dump_desc - describes the dump
|
||||||
@ -384,4 +385,7 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
|
|||||||
void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt);
|
void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt);
|
||||||
void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt);
|
void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt);
|
||||||
void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt);
|
void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt);
|
||||||
|
void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
|
||||||
|
enum iwl_fw_ini_apply_point apply_point);
|
||||||
|
|
||||||
#endif /* __iwl_fw_dbg_h__ */
|
#endif /* __iwl_fw_dbg_h__ */
|
||||||
|
@ -65,6 +65,8 @@
|
|||||||
#define __iwl_fw_img_h__
|
#define __iwl_fw_img_h__
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#include "api/dbg-tlv.h"
|
||||||
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "error-dump.h"
|
#include "error-dump.h"
|
||||||
|
|
||||||
@ -220,6 +222,30 @@ struct iwl_fw_dbg {
|
|||||||
u32 dump_mask;
|
u32 dump_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_fw_ini_active_triggers
|
||||||
|
* @active: is this trigger active
|
||||||
|
* @apply_point: last apply point that updated this trigger
|
||||||
|
* @conf: active trigger
|
||||||
|
* @conf_ext: second trigger, contains extra regions to dump
|
||||||
|
*/
|
||||||
|
struct iwl_fw_ini_active_triggers {
|
||||||
|
bool active;
|
||||||
|
enum iwl_fw_ini_apply_point apply_point;
|
||||||
|
struct iwl_fw_ini_trigger *conf;
|
||||||
|
struct iwl_fw_ini_trigger *conf_ext;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_fw_ini_active_regs
|
||||||
|
* @reg: active region from TLV
|
||||||
|
* @apply_point: apply point where it became active
|
||||||
|
*/
|
||||||
|
struct iwl_fw_ini_active_regs {
|
||||||
|
struct iwl_fw_ini_region_cfg *reg;
|
||||||
|
enum iwl_fw_ini_apply_point apply_point;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_fw - variables associated with the firmware
|
* struct iwl_fw - variables associated with the firmware
|
||||||
*
|
*
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
#include "iwl-trans.h"
|
#include "iwl-trans.h"
|
||||||
#include "img.h"
|
#include "img.h"
|
||||||
#include "fw/api/debug.h"
|
#include "fw/api/debug.h"
|
||||||
|
#include "fw/api/dbg-tlv.h"
|
||||||
#include "fw/api/paging.h"
|
#include "fw/api/paging.h"
|
||||||
#include "iwl-eeprom-parse.h"
|
#include "iwl-eeprom-parse.h"
|
||||||
|
|
||||||
@ -139,6 +140,8 @@ struct iwl_fw_runtime {
|
|||||||
/* ts of the beginning of a non-collect fw dbg data period */
|
/* ts of the beginning of a non-collect fw dbg data period */
|
||||||
unsigned long non_collect_ts_start[FW_DBG_TRIGGER_MAX - 1];
|
unsigned long non_collect_ts_start[FW_DBG_TRIGGER_MAX - 1];
|
||||||
u32 *d3_debug_data;
|
u32 *d3_debug_data;
|
||||||
|
struct iwl_fw_ini_active_regs active_regs[IWL_FW_INI_MAX_REGION_ID];
|
||||||
|
struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM];
|
||||||
} dump;
|
} dump;
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||||
struct {
|
struct {
|
||||||
|
@ -123,6 +123,9 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
|
|||||||
hdr = (void *)&tlv->data[0];
|
hdr = (void *)&tlv->data[0];
|
||||||
apply = le32_to_cpu(hdr->apply_point);
|
apply = le32_to_cpu(hdr->apply_point);
|
||||||
|
|
||||||
|
IWL_DEBUG_FW(trans, "Read TLV %x, apply point %d\n",
|
||||||
|
le32_to_cpu(tlv->type), apply);
|
||||||
|
|
||||||
if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM))
|
if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -680,7 +680,6 @@ enum iwl_plat_pm_mode {
|
|||||||
* enter/exit (in msecs).
|
* enter/exit (in msecs).
|
||||||
*/
|
*/
|
||||||
#define IWL_TRANS_IDLE_TIMEOUT 2000
|
#define IWL_TRANS_IDLE_TIMEOUT 2000
|
||||||
#define IWL_MAX_DEBUG_ALLOCATIONS 1
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_dram_data
|
* struct iwl_dram_data
|
||||||
@ -786,7 +785,7 @@ struct iwl_trans {
|
|||||||
struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv;
|
struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv;
|
||||||
u8 dbg_n_dest_reg;
|
u8 dbg_n_dest_reg;
|
||||||
int num_blocks;
|
int num_blocks;
|
||||||
struct iwl_dram_data fw_mon[IWL_MAX_DEBUG_ALLOCATIONS];
|
struct iwl_dram_data fw_mon[IWL_FW_INI_APPLY_NUM];
|
||||||
|
|
||||||
enum iwl_plat_pm_mode system_pm_mode;
|
enum iwl_plat_pm_mode system_pm_mode;
|
||||||
enum iwl_plat_pm_mode runtime_pm_mode;
|
enum iwl_plat_pm_mode runtime_pm_mode;
|
||||||
|
Loading…
Reference in New Issue
Block a user