iwlwifi: trans: support loading ini TLVs from external file
Support loading and storing ini TLVs from external file. Those TLVs are appended to the default TLVs, so store them separately. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
f14cda6f3b
commit
68f6f492c4
4 changed files with 89 additions and 11 deletions
|
@ -63,7 +63,8 @@
|
||||||
#include "iwl-trans.h"
|
#include "iwl-trans.h"
|
||||||
#include "iwl-dbg-tlv.h"
|
#include "iwl-dbg-tlv.h"
|
||||||
|
|
||||||
void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv)
|
void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
|
||||||
|
bool ext)
|
||||||
{
|
{
|
||||||
struct iwl_apply_point_data *data;
|
struct iwl_apply_point_data *data;
|
||||||
struct iwl_fw_ini_header *header = (void *)&tlv->data[0];
|
struct iwl_fw_ini_header *header = (void *)&tlv->data[0];
|
||||||
|
@ -75,6 +76,9 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv)
|
||||||
"Invalid apply point id %d\n", apply_point))
|
"Invalid apply point id %d\n", apply_point))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (ext)
|
||||||
|
data = &trans->apply_points_ext[apply_point];
|
||||||
|
else
|
||||||
data = &trans->apply_points[apply_point];
|
data = &trans->apply_points[apply_point];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -90,7 +94,8 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv)
|
||||||
data->offset += copy_size;
|
data->offset += copy_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data)
|
void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
|
||||||
|
bool ext)
|
||||||
{
|
{
|
||||||
struct iwl_ucode_tlv *tlv;
|
struct iwl_ucode_tlv *tlv;
|
||||||
u32 size[IWL_FW_INI_APPLY_NUM] = {0};
|
u32 size[IWL_FW_INI_APPLY_NUM] = {0};
|
||||||
|
@ -137,10 +142,15 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ext) {
|
||||||
|
trans->apply_points_ext[i].data = mem;
|
||||||
|
trans->apply_points_ext[i].size = size[i];
|
||||||
|
} else {
|
||||||
trans->apply_points[i].data = mem;
|
trans->apply_points[i].data = mem;
|
||||||
trans->apply_points[i].size = size[i];
|
trans->apply_points[i].size = size[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void iwl_fw_dbg_free(struct iwl_trans *trans)
|
void iwl_fw_dbg_free(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
|
@ -150,5 +160,66 @@ void iwl_fw_dbg_free(struct iwl_trans *trans)
|
||||||
kfree(trans->apply_points[i].data);
|
kfree(trans->apply_points[i].data);
|
||||||
trans->apply_points[i].size = 0;
|
trans->apply_points[i].size = 0;
|
||||||
trans->apply_points[i].offset = 0;
|
trans->apply_points[i].offset = 0;
|
||||||
|
|
||||||
|
kfree(trans->apply_points_ext[i].data);
|
||||||
|
trans->apply_points_ext[i].size = 0;
|
||||||
|
trans->apply_points_ext[i].offset = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
struct iwl_ucode_tlv *tlv;
|
||||||
|
enum iwl_ucode_tlv_type tlv_type;
|
||||||
|
u32 tlv_len;
|
||||||
|
|
||||||
|
while (len >= sizeof(*tlv)) {
|
||||||
|
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, tlv_len);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
len -= ALIGN(tlv_len, 4);
|
||||||
|
data += sizeof(*tlv) + ALIGN(tlv_len, 4);
|
||||||
|
|
||||||
|
switch (tlv_type) {
|
||||||
|
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_fw_dbg_copy_tlv(trans, tlv, true);
|
||||||
|
default:
|
||||||
|
WARN_ONCE(1, "Invalid TLV %x\n", tlv_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans)
|
||||||
|
{
|
||||||
|
const struct firmware *fw;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (trans->external_ini_loaded || !iwlwifi_mod_params.enable_ini)
|
||||||
|
return;
|
||||||
|
|
||||||
|
res = request_firmware(&fw, "iwl-dbg-tlv.ini", dev);
|
||||||
|
if (res)
|
||||||
|
return;
|
||||||
|
|
||||||
|
iwl_alloc_dbg_tlv(trans, fw->size, fw->data, true);
|
||||||
|
iwl_parse_fw_dbg_tlv(trans, fw->data, fw->size);
|
||||||
|
|
||||||
|
trans->external_ini_loaded = true;
|
||||||
|
release_firmware(fw);
|
||||||
|
}
|
||||||
|
|
|
@ -77,8 +77,11 @@ struct iwl_apply_point_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct iwl_trans;
|
struct iwl_trans;
|
||||||
|
void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans);
|
||||||
void iwl_fw_dbg_free(struct iwl_trans *trans);
|
void iwl_fw_dbg_free(struct iwl_trans *trans);
|
||||||
void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv);
|
void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
|
||||||
void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data);
|
bool ext);
|
||||||
|
void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
|
||||||
|
bool ext);
|
||||||
|
|
||||||
#endif /* __iwl_dbg_tlv_h__*/
|
#endif /* __iwl_dbg_tlv_h__*/
|
||||||
|
|
|
@ -647,7 +647,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||||
len -= sizeof(*ucode);
|
len -= sizeof(*ucode);
|
||||||
|
|
||||||
if (iwlwifi_mod_params.enable_ini)
|
if (iwlwifi_mod_params.enable_ini)
|
||||||
iwl_alloc_dbg_tlv(drv->trans, len, data);
|
iwl_alloc_dbg_tlv(drv->trans, len, data, false);
|
||||||
|
|
||||||
while (len >= sizeof(*tlv)) {
|
while (len >= sizeof(*tlv)) {
|
||||||
len -= sizeof(*tlv);
|
len -= sizeof(*tlv);
|
||||||
|
@ -1096,7 +1096,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||||
case IWL_UCODE_TLV_TYPE_TRIGGERS:
|
case IWL_UCODE_TLV_TYPE_TRIGGERS:
|
||||||
case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
|
case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
|
||||||
if (iwlwifi_mod_params.enable_ini)
|
if (iwlwifi_mod_params.enable_ini)
|
||||||
iwl_fw_dbg_copy_tlv(drv->trans, tlv);
|
iwl_fw_dbg_copy_tlv(drv->trans, tlv, false);
|
||||||
default:
|
default:
|
||||||
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
|
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
|
||||||
break;
|
break;
|
||||||
|
@ -1576,7 +1576,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
|
||||||
if (!drv->dbgfs_drv) {
|
if (!drv->dbgfs_drv) {
|
||||||
IWL_ERR(drv, "failed to create debugfs directory\n");
|
IWL_ERR(drv, "failed to create debugfs directory\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_free_drv;
|
goto err_free_tlv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create transport layer debugfs dir */
|
/* Create transport layer debugfs dir */
|
||||||
|
@ -1601,7 +1601,8 @@ err_fw:
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||||
err_free_dbgfs:
|
err_free_dbgfs:
|
||||||
debugfs_remove_recursive(drv->dbgfs_drv);
|
debugfs_remove_recursive(drv->dbgfs_drv);
|
||||||
err_free_drv:
|
err_free_tlv:
|
||||||
|
iwl_fw_dbg_free(drv->trans);
|
||||||
#endif
|
#endif
|
||||||
kfree(drv);
|
kfree(drv);
|
||||||
err:
|
err:
|
||||||
|
|
|
@ -776,6 +776,9 @@ struct iwl_trans {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct iwl_apply_point_data apply_points[IWL_FW_INI_APPLY_NUM];
|
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];
|
||||||
|
|
||||||
|
bool external_ini_loaded;
|
||||||
|
|
||||||
const struct iwl_fw_dbg_dest_tlv_v1 *dbg_dest_tlv;
|
const struct iwl_fw_dbg_dest_tlv_v1 *dbg_dest_tlv;
|
||||||
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
||||||
|
|
Loading…
Add table
Reference in a new issue