Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b081e23c authored by Johannes Berg's avatar Johannes Berg Committed by Luca Coelho
Browse files

iwlwifi: parse command version TLV



In newer firmware images there's a command version TLV that
states, for each listed command or notification, which version
of the command and/or notification structure is used. Read and
keep this data to be able to use it in the future.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 1da3823d
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ enum iwl_ucode_tlv_type {
	IWL_UCODE_TLV_FW_DBG_DEST	= 38,
	IWL_UCODE_TLV_FW_DBG_CONF	= 39,
	IWL_UCODE_TLV_FW_DBG_TRIGGER	= 40,
	IWL_UCODE_TLV_CMD_VERSIONS	= 48,
	IWL_UCODE_TLV_FW_GSCAN_CAPA	= 50,
	IWL_UCODE_TLV_FW_MEM_SEG	= 51,
	IWL_UCODE_TLV_IML		= 52,
@@ -943,4 +944,20 @@ struct iwl_fw_dbg_conf_tlv {
	struct iwl_fw_dbg_conf_hcmd hcmd;
} __packed;

#define IWL_FW_CMD_VER_UNKNOWN 99

/**
 * struct iwl_fw_cmd_version - firmware command version entry
 * @cmd: command ID
 * @group: group ID
 * @cmd_ver: command version
 * @notif_ver: notification version
 */
struct iwl_fw_cmd_version {
	u8 cmd;
	u8 group;
	u8 cmd_ver;
	u8 notif_ver;
} __packed;

#endif  /* __iwl_fw_file_h__ */
+5 −2
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@
 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 * Copyright(c) 2016        Intel Deutschland GmbH
 * Copyright(c) 2018 Intel Corporation
 * Copyright(c) 2018 - 2019 Intel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 * Copyright(c) 2016        Intel Deutschland GmbH
 * Copyright(c) 2018 Intel Corporation
 * Copyright(c) 2018 - 2019 Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -109,6 +109,9 @@ struct iwl_ucode_capabilities {
	u32 error_log_size;
	unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)];
	unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)];

	const struct iwl_fw_cmd_version *cmd_versions;
	u32 n_cmd_versions;
};

static inline bool
+18 −0
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
		kfree(drv->fw.dbg.trigger_tlv[i]);
	kfree(drv->fw.dbg.mem_tlv);
	kfree(drv->fw.iml);
	kfree(drv->fw.ucode_capa.cmd_versions);

	for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
		iwl_free_fw_img(drv, drv->fw.img + i);
@@ -1144,6 +1145,23 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
			if (iwlwifi_mod_params.enable_ini)
				iwl_fw_dbg_copy_tlv(drv->trans, tlv, false);
			break;
		case IWL_UCODE_TLV_CMD_VERSIONS:
			if (tlv_len % sizeof(struct iwl_fw_cmd_version)) {
				IWL_ERR(drv,
					"Invalid length for command versions: %u\n",
					tlv_len);
				tlv_len /= sizeof(struct iwl_fw_cmd_version);
				tlv_len *= sizeof(struct iwl_fw_cmd_version);
			}
			if (WARN_ON(capa->cmd_versions))
				return -EINVAL;
			capa->cmd_versions = kmemdup(tlv_data, tlv_len,
						     GFP_KERNEL);
			if (!capa->cmd_versions)
				return -ENOMEM;
			capa->n_cmd_versions =
				tlv_len / sizeof(struct iwl_fw_cmd_version);
			break;
		default:
			IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
			break;