summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
diff options
context:
space:
mode:
authorShahar S Matityahu <shahar.s.matityahu@intel.com>2019-06-10 16:14:20 +0300
committerLuca Coelho <luciano.coelho@intel.com>2019-09-06 15:31:18 +0300
commit40b7d22d1f0e9697bb78c9da377e06efa925d035 (patch)
tree898fb6b578dcb3090bdb1cfaaa02ea02d10f0a7a /drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
parentccdc3d6d15555b170a977e9dd82c5e9db465f10a (diff)
iwlwifi: dbg_ini: use linked list to store debug TLVs
Use a linked list to maintain the debug TLVs instead of a single buffer. This way, the driver does not need to iterate over the binary file twice and allocates smaller chunks of memory. Also, in case one allocation fails the driver will work with the partial configuration instead of aborting the entire debug configuration. Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c121
1 files changed, 37 insertions, 84 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 5948d769eed0..7c1e76ee7ede 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -66,102 +66,56 @@
void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
bool ext)
{
- struct iwl_apply_point_data *data;
+ 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);
+ u32 len = le32_to_cpu(tlv->length);
u32 apply_point = le32_to_cpu(header->apply_point);
- int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv);
- int offset_size = copy_size;
-
if (le32_to_cpu(header->tlv_version) != 1)
return;
if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
- "Invalid apply point id %d\n", apply_point))
+ "Invalid apply point %d\n", apply_point))
return;
+ IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
+ tlv_type, apply_point);
+
if (ext)
- data = &trans->dbg.apply_points_ext[apply_point];
+ dbg_cfg = &trans->dbg.apply_points_ext[apply_point];
else
- data = &trans->dbg.apply_points[apply_point];
-
- /*
- * Make sure we still have room to copy this TLV. Offset points to the
- * location the last copy ended.
- */
- if (WARN_ONCE(data->offset + offset_size > data->size,
- "Not enough memory for apply point %d\n",
- apply_point))
- return;
-
- memcpy(data->data + data->offset, (void *)tlv, copy_size);
- data->offset += offset_size;
-}
-
-void iwl_dbg_tlv_alloc(struct iwl_trans *trans, size_t len, const u8 *data,
- bool ext)
-{
- struct iwl_ucode_tlv *tlv;
- u32 size[IWL_FW_INI_APPLY_NUM] = {0};
- int i;
-
- while (len >= sizeof(*tlv)) {
- u32 tlv_len, tlv_type, apply;
- struct iwl_fw_ini_header *hdr;
-
- len -= sizeof(*tlv);
- tlv = (void *)data;
-
- tlv_len = le32_to_cpu(tlv->length);
- tlv_type = le32_to_cpu(tlv->type);
+ dbg_cfg = &trans->dbg.apply_points[apply_point];
- if (len < tlv_len)
- return;
-
- len -= ALIGN(tlv_len, 4);
- data += sizeof(*tlv) + ALIGN(tlv_len, 4);
-
- if (tlv_type < IWL_UCODE_TLV_DEBUG_BASE ||
- tlv_type > IWL_UCODE_TLV_DEBUG_MAX)
- continue;
-
- hdr = (void *)&tlv->data[0];
- apply = le32_to_cpu(hdr->apply_point);
-
- if (le32_to_cpu(hdr->tlv_version) != 1)
- continue;
-
- IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
- le32_to_cpu(tlv->type), apply);
-
- if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM))
- continue;
-
- size[apply] += sizeof(*tlv) + tlv_len;
+ 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;
}
- for (i = 0; i < ARRAY_SIZE(size); i++) {
- void *mem;
+ INIT_LIST_HEAD(&tlv_copy->list);
+ memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len);
- if (!size[i])
- continue;
+ if (!dbg_cfg->list.next)
+ INIT_LIST_HEAD(&dbg_cfg->list);
- mem = kzalloc(size[i], GFP_KERNEL);
+ list_add_tail(&tlv_copy->list, &dbg_cfg->list);
- if (!mem) {
- IWL_ERR(trans, "No memory for apply point %d\n", i);
- return;
- }
+ trans->dbg.ini_valid = true;
+}
- if (ext) {
- trans->dbg.apply_points_ext[i].data = mem;
- trans->dbg.apply_points_ext[i].size = size[i];
- } else {
- trans->dbg.apply_points[i].data = mem;
- trans->dbg.apply_points[i].size = size[i];
- }
+static void iwl_dbg_tlv_free_list(struct list_head *list)
+{
+ if (!list || !list->next)
+ return;
- trans->dbg.ini_valid = true;
+ while (!list_empty(list)) {
+ struct iwl_apply_point_data *node =
+ list_entry(list->next, typeof(*node), list);
+
+ list_del(&node->list);
+ kfree(node);
}
}
@@ -170,13 +124,13 @@ void iwl_dbg_tlv_free(struct iwl_trans *trans)
int i;
for (i = 0; i < ARRAY_SIZE(trans->dbg.apply_points); i++) {
- kfree(trans->dbg.apply_points[i].data);
- trans->dbg.apply_points[i].size = 0;
- trans->dbg.apply_points[i].offset = 0;
+ struct iwl_apply_point_data *data;
+
+ data = &trans->dbg.apply_points[i];
+ iwl_dbg_tlv_free_list(&data->list);
- kfree(trans->dbg.apply_points_ext[i].data);
- trans->dbg.apply_points_ext[i].size = 0;
- trans->dbg.apply_points_ext[i].offset = 0;
+ data = &trans->dbg.apply_points_ext[i];
+ iwl_dbg_tlv_free_list(&data->list);
}
}
@@ -232,7 +186,6 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
if (res)
return;
- iwl_dbg_tlv_alloc(trans, fw->size, fw->data, true);
iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size);
trans->dbg.external_ini_loaded = true;