18e99ea8dSJohannes Berg /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
28e99ea8dSJohannes Berg /*
34f7411d6SRoee Goldfiner * Copyright (C) 2005-2014, 2018-2021 Intel Corporation
48e99ea8dSJohannes Berg * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
58e99ea8dSJohannes Berg * Copyright (C) 2016 Intel Deutschland GmbH
68e99ea8dSJohannes Berg */
7d962f9b1SJohannes Berg #ifndef __iwl_fw_img_h__
8d962f9b1SJohannes Berg #define __iwl_fw_img_h__
9d962f9b1SJohannes Berg #include <linux/types.h>
10d962f9b1SJohannes Berg
11d47902f9SSara Sharon #include "api/dbg-tlv.h"
12d47902f9SSara Sharon
13d962f9b1SJohannes Berg #include "file.h"
14d962f9b1SJohannes Berg #include "error-dump.h"
15d962f9b1SJohannes Berg
16d962f9b1SJohannes Berg /**
17d962f9b1SJohannes Berg * enum iwl_ucode_type
18d962f9b1SJohannes Berg *
19d962f9b1SJohannes Berg * The type of ucode.
20d962f9b1SJohannes Berg *
21d962f9b1SJohannes Berg * @IWL_UCODE_REGULAR: Normal runtime ucode
22d962f9b1SJohannes Berg * @IWL_UCODE_INIT: Initial ucode
23d962f9b1SJohannes Berg * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
24d962f9b1SJohannes Berg * @IWL_UCODE_REGULAR_USNIFFER: Normal runtime ucode when using usniffer image
25d962f9b1SJohannes Berg */
26d962f9b1SJohannes Berg enum iwl_ucode_type {
27d962f9b1SJohannes Berg IWL_UCODE_REGULAR,
28d962f9b1SJohannes Berg IWL_UCODE_INIT,
29d962f9b1SJohannes Berg IWL_UCODE_WOWLAN,
30d962f9b1SJohannes Berg IWL_UCODE_REGULAR_USNIFFER,
31d962f9b1SJohannes Berg IWL_UCODE_TYPE_MAX,
32d962f9b1SJohannes Berg };
33d962f9b1SJohannes Berg
34d962f9b1SJohannes Berg /*
35d962f9b1SJohannes Berg * enumeration of ucode section.
36d962f9b1SJohannes Berg * This enumeration is used directly for older firmware (before 16.0).
37d962f9b1SJohannes Berg * For new firmware, there can be up to 4 sections (see below) but the
38d962f9b1SJohannes Berg * first one packaged into the firmware file is the DATA section and
39d962f9b1SJohannes Berg * some debugging code accesses that.
40d962f9b1SJohannes Berg */
41d962f9b1SJohannes Berg enum iwl_ucode_sec {
42d962f9b1SJohannes Berg IWL_UCODE_SECTION_DATA,
43d962f9b1SJohannes Berg IWL_UCODE_SECTION_INST,
44d962f9b1SJohannes Berg };
45d962f9b1SJohannes Berg
46d962f9b1SJohannes Berg struct iwl_ucode_capabilities {
47d962f9b1SJohannes Berg u32 max_probe_length;
48d962f9b1SJohannes Berg u32 n_scan_channels;
49d962f9b1SJohannes Berg u32 standard_phy_calibration_size;
50d962f9b1SJohannes Berg u32 flags;
51f130bb75SMordechay Goodstein u32 error_log_addr;
52f130bb75SMordechay Goodstein u32 error_log_size;
53be9ae34eSNathan Errera u32 num_stations;
54*d9bfd5a0SJohannes Berg u32 num_beacons;
55d962f9b1SJohannes Berg unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)];
56d962f9b1SJohannes Berg unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)];
57b081e23cSJohannes Berg
58b081e23cSJohannes Berg const struct iwl_fw_cmd_version *cmd_versions;
59b081e23cSJohannes Berg u32 n_cmd_versions;
60d962f9b1SJohannes Berg };
61d962f9b1SJohannes Berg
62d962f9b1SJohannes Berg static inline bool
fw_has_api(const struct iwl_ucode_capabilities * capabilities,iwl_ucode_tlv_api_t api)63d962f9b1SJohannes Berg fw_has_api(const struct iwl_ucode_capabilities *capabilities,
64d962f9b1SJohannes Berg iwl_ucode_tlv_api_t api)
65d962f9b1SJohannes Berg {
66d962f9b1SJohannes Berg return test_bit((__force long)api, capabilities->_api);
67d962f9b1SJohannes Berg }
68d962f9b1SJohannes Berg
69d962f9b1SJohannes Berg static inline bool
fw_has_capa(const struct iwl_ucode_capabilities * capabilities,iwl_ucode_tlv_capa_t capa)70d962f9b1SJohannes Berg fw_has_capa(const struct iwl_ucode_capabilities *capabilities,
71d962f9b1SJohannes Berg iwl_ucode_tlv_capa_t capa)
72d962f9b1SJohannes Berg {
73d962f9b1SJohannes Berg return test_bit((__force long)capa, capabilities->_capa);
74d962f9b1SJohannes Berg }
75d962f9b1SJohannes Berg
76d962f9b1SJohannes Berg /* one for each uCode image (inst/data, init/runtime/wowlan) */
77d962f9b1SJohannes Berg struct fw_desc {
78d962f9b1SJohannes Berg const void *data; /* vmalloc'ed data */
79d962f9b1SJohannes Berg u32 len; /* size in bytes */
80d962f9b1SJohannes Berg u32 offset; /* offset in the device */
81d962f9b1SJohannes Berg };
82d962f9b1SJohannes Berg
83d962f9b1SJohannes Berg struct fw_img {
84d962f9b1SJohannes Berg struct fw_desc *sec;
85d962f9b1SJohannes Berg int num_sec;
86d962f9b1SJohannes Berg bool is_dual_cpus;
87d962f9b1SJohannes Berg u32 paging_mem_size;
88d962f9b1SJohannes Berg };
89d962f9b1SJohannes Berg
90d962f9b1SJohannes Berg /*
91d962f9b1SJohannes Berg * Block paging calculations
92d962f9b1SJohannes Berg */
93d962f9b1SJohannes Berg #define PAGE_2_EXP_SIZE 12 /* 4K == 2^12 */
94d962f9b1SJohannes Berg #define FW_PAGING_SIZE BIT(PAGE_2_EXP_SIZE) /* page size is 4KB */
95d962f9b1SJohannes Berg #define PAGE_PER_GROUP_2_EXP_SIZE 3
96d962f9b1SJohannes Berg /* 8 pages per group */
97d962f9b1SJohannes Berg #define NUM_OF_PAGE_PER_GROUP BIT(PAGE_PER_GROUP_2_EXP_SIZE)
98d962f9b1SJohannes Berg /* don't change, support only 32KB size */
99d962f9b1SJohannes Berg #define PAGING_BLOCK_SIZE (NUM_OF_PAGE_PER_GROUP * FW_PAGING_SIZE)
100d962f9b1SJohannes Berg /* 32K == 2^15 */
101d962f9b1SJohannes Berg #define BLOCK_2_EXP_SIZE (PAGE_2_EXP_SIZE + PAGE_PER_GROUP_2_EXP_SIZE)
102d962f9b1SJohannes Berg
103d962f9b1SJohannes Berg /*
104d962f9b1SJohannes Berg * Image paging calculations
105d962f9b1SJohannes Berg */
106d962f9b1SJohannes Berg #define BLOCK_PER_IMAGE_2_EXP_SIZE 5
107d962f9b1SJohannes Berg /* 2^5 == 32 blocks per image */
108d962f9b1SJohannes Berg #define NUM_OF_BLOCK_PER_IMAGE BIT(BLOCK_PER_IMAGE_2_EXP_SIZE)
109d962f9b1SJohannes Berg /* maximum image size 1024KB */
110d962f9b1SJohannes Berg #define MAX_PAGING_IMAGE_SIZE (NUM_OF_BLOCK_PER_IMAGE * PAGING_BLOCK_SIZE)
111d962f9b1SJohannes Berg
112d962f9b1SJohannes Berg /* Virtual address signature */
113d962f9b1SJohannes Berg #define PAGING_ADDR_SIG 0xAA000000
114d962f9b1SJohannes Berg
115d962f9b1SJohannes Berg #define PAGING_CMD_IS_SECURED BIT(9)
116d962f9b1SJohannes Berg #define PAGING_CMD_IS_ENABLED BIT(8)
117d962f9b1SJohannes Berg #define PAGING_CMD_NUM_OF_PAGES_IN_LAST_GRP_POS 0
118d962f9b1SJohannes Berg #define PAGING_TLV_SECURE_MASK 1
119d962f9b1SJohannes Berg
1204f7411d6SRoee Goldfiner /* FW MSB Mask for regions/cache_control */
1214f7411d6SRoee Goldfiner #define FW_ADDR_CACHE_CONTROL 0xC0000000UL
1224f7411d6SRoee Goldfiner
123d962f9b1SJohannes Berg /**
124d962f9b1SJohannes Berg * struct iwl_fw_paging
125d962f9b1SJohannes Berg * @fw_paging_phys: page phy pointer
126d962f9b1SJohannes Berg * @fw_paging_block: pointer to the allocated block
127d962f9b1SJohannes Berg * @fw_paging_size: page size
128fdb70083SJohannes Berg * @fw_offs: offset in the device
129d962f9b1SJohannes Berg */
130d962f9b1SJohannes Berg struct iwl_fw_paging {
131d962f9b1SJohannes Berg dma_addr_t fw_paging_phys;
132d962f9b1SJohannes Berg struct page *fw_paging_block;
133d962f9b1SJohannes Berg u32 fw_paging_size;
134fdb70083SJohannes Berg u32 fw_offs;
135d962f9b1SJohannes Berg };
136d962f9b1SJohannes Berg
137d962f9b1SJohannes Berg /**
138d962f9b1SJohannes Berg * enum iwl_fw_type - iwlwifi firmware type
139d962f9b1SJohannes Berg * @IWL_FW_DVM: DVM firmware
140d962f9b1SJohannes Berg * @IWL_FW_MVM: MVM firmware
141d962f9b1SJohannes Berg */
142d962f9b1SJohannes Berg enum iwl_fw_type {
143d962f9b1SJohannes Berg IWL_FW_DVM,
144d962f9b1SJohannes Berg IWL_FW_MVM,
145d962f9b1SJohannes Berg };
146d962f9b1SJohannes Berg
147d962f9b1SJohannes Berg /**
14817b809c9SSara Sharon * struct iwl_fw_dbg - debug data
14917b809c9SSara Sharon *
15017b809c9SSara Sharon * @dest_tlv: points to debug destination TLV (typically SRAM or DRAM)
15117b809c9SSara Sharon * @n_dest_reg: num of reg_ops in dest_tlv
15217b809c9SSara Sharon * @conf_tlv: array of pointers to configuration HCMDs
15317b809c9SSara Sharon * @trigger_tlv: array of pointers to triggers TLVs
15417b809c9SSara Sharon * @trigger_tlv_len: lengths of the @dbg_trigger_tlv entries
15517b809c9SSara Sharon * @mem_tlv: Runtime addresses to dump
15617b809c9SSara Sharon * @n_mem_tlv: number of runtime addresses
15717b809c9SSara Sharon * @dump_mask: bitmask of dump regions
15817b809c9SSara Sharon */
15917b809c9SSara Sharon struct iwl_fw_dbg {
16017b809c9SSara Sharon struct iwl_fw_dbg_dest_tlv_v1 *dest_tlv;
16117b809c9SSara Sharon u8 n_dest_reg;
16217b809c9SSara Sharon struct iwl_fw_dbg_conf_tlv *conf_tlv[FW_DBG_CONF_MAX];
16317b809c9SSara Sharon struct iwl_fw_dbg_trigger_tlv *trigger_tlv[FW_DBG_TRIGGER_MAX];
16417b809c9SSara Sharon size_t trigger_tlv_len[FW_DBG_TRIGGER_MAX];
16517b809c9SSara Sharon struct iwl_fw_dbg_mem_seg_tlv *mem_tlv;
16617b809c9SSara Sharon size_t n_mem_tlv;
16717b809c9SSara Sharon u32 dump_mask;
16817b809c9SSara Sharon };
16917b809c9SSara Sharon
170fad92a1dSJohannes Berg struct iwl_dump_exclude {
171fad92a1dSJohannes Berg u32 addr, size;
172fad92a1dSJohannes Berg };
173fad92a1dSJohannes Berg
17417b809c9SSara Sharon /**
175d962f9b1SJohannes Berg * struct iwl_fw - variables associated with the firmware
176d962f9b1SJohannes Berg *
177d962f9b1SJohannes Berg * @ucode_ver: ucode version from the ucode file
178d962f9b1SJohannes Berg * @fw_version: firmware version string
179d962f9b1SJohannes Berg * @img: ucode image like ucode_rt, ucode_init, ucode_wowlan.
180132db31cSGolan Ben-Ami * @iml_len: length of the image loader image
181132db31cSGolan Ben-Ami * @iml: image loader fw image
182d962f9b1SJohannes Berg * @ucode_capa: capabilities parsed from the ucode file.
183d962f9b1SJohannes Berg * @enhance_sensitivity_table: device can do enhanced sensitivity.
184d962f9b1SJohannes Berg * @init_evtlog_ptr: event log offset for init ucode.
185d962f9b1SJohannes Berg * @init_evtlog_size: event log size for init ucode.
186e2e76bdcSJulia Lawall * @init_errlog_ptr: error log offset for init ucode.
187d962f9b1SJohannes Berg * @inst_evtlog_ptr: event log offset for runtime ucode.
188d962f9b1SJohannes Berg * @inst_evtlog_size: event log size for runtime ucode.
189e2e76bdcSJulia Lawall * @inst_errlog_ptr: error log offset for runtime ucode.
190d962f9b1SJohannes Berg * @type: firmware type (&enum iwl_fw_type)
191d962f9b1SJohannes Berg * @human_readable: human readable version
192d962f9b1SJohannes Berg * we get the ALIVE from the uCode
193e79b2fc9SJohannes Berg * @phy_integration_ver: PHY integration version string
194e79b2fc9SJohannes Berg * @phy_integration_ver_len: length of @phy_integration_ver
195fad92a1dSJohannes Berg * @dump_excl: image dump exclusion areas for RT image
196fad92a1dSJohannes Berg * @dump_excl_wowlan: image dump exclusion areas for WoWLAN image
197d962f9b1SJohannes Berg */
198d962f9b1SJohannes Berg struct iwl_fw {
199d962f9b1SJohannes Berg u32 ucode_ver;
200d962f9b1SJohannes Berg
20155b514b4SJohannes Berg char fw_version[64];
202d962f9b1SJohannes Berg
203d962f9b1SJohannes Berg /* ucode images */
204d962f9b1SJohannes Berg struct fw_img img[IWL_UCODE_TYPE_MAX];
205132db31cSGolan Ben-Ami size_t iml_len;
206132db31cSGolan Ben-Ami u8 *iml;
207d962f9b1SJohannes Berg
208d962f9b1SJohannes Berg struct iwl_ucode_capabilities ucode_capa;
209d962f9b1SJohannes Berg bool enhance_sensitivity_table;
210d962f9b1SJohannes Berg
211d962f9b1SJohannes Berg u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
212d962f9b1SJohannes Berg u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
213d962f9b1SJohannes Berg
214d962f9b1SJohannes Berg struct iwl_tlv_calib_ctrl default_calib[IWL_UCODE_TYPE_MAX];
215d962f9b1SJohannes Berg u32 phy_config;
216d962f9b1SJohannes Berg u8 valid_tx_ant;
217d962f9b1SJohannes Berg u8 valid_rx_ant;
218d962f9b1SJohannes Berg
219d962f9b1SJohannes Berg enum iwl_fw_type type;
220d962f9b1SJohannes Berg
221d962f9b1SJohannes Berg u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
222d962f9b1SJohannes Berg
22317b809c9SSara Sharon struct iwl_fw_dbg dbg;
224a1d59263SDror Moshe
225a1d59263SDror Moshe u8 *phy_integration_ver;
226a1d59263SDror Moshe u32 phy_integration_ver_len;
227fad92a1dSJohannes Berg
228fad92a1dSJohannes Berg struct iwl_dump_exclude dump_excl[2], dump_excl_wowlan[2];
229d962f9b1SJohannes Berg };
230d962f9b1SJohannes Berg
get_fw_dbg_mode_string(int mode)231d962f9b1SJohannes Berg static inline const char *get_fw_dbg_mode_string(int mode)
232d962f9b1SJohannes Berg {
233d962f9b1SJohannes Berg switch (mode) {
234d962f9b1SJohannes Berg case SMEM_MODE:
235d962f9b1SJohannes Berg return "SMEM";
236d962f9b1SJohannes Berg case EXTERNAL_MODE:
237d962f9b1SJohannes Berg return "EXTERNAL_DRAM";
238d962f9b1SJohannes Berg case MARBH_MODE:
239d962f9b1SJohannes Berg return "MARBH";
240d962f9b1SJohannes Berg case MIPI_MODE:
241d962f9b1SJohannes Berg return "MIPI";
242d962f9b1SJohannes Berg default:
243d962f9b1SJohannes Berg return "UNKNOWN";
244d962f9b1SJohannes Berg }
245d962f9b1SJohannes Berg }
246d962f9b1SJohannes Berg
247d962f9b1SJohannes Berg static inline bool
iwl_fw_dbg_conf_usniffer(const struct iwl_fw * fw,u8 id)248d962f9b1SJohannes Berg iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id)
249d962f9b1SJohannes Berg {
25017b809c9SSara Sharon const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg.conf_tlv[id];
251d962f9b1SJohannes Berg
252d962f9b1SJohannes Berg if (!conf_tlv)
253d962f9b1SJohannes Berg return false;
254d962f9b1SJohannes Berg
255d962f9b1SJohannes Berg return conf_tlv->usniffer;
256d962f9b1SJohannes Berg }
257d962f9b1SJohannes Berg
258d962f9b1SJohannes Berg static inline const struct fw_img *
iwl_get_ucode_image(const struct iwl_fw * fw,enum iwl_ucode_type ucode_type)259d962f9b1SJohannes Berg iwl_get_ucode_image(const struct iwl_fw *fw, enum iwl_ucode_type ucode_type)
260d962f9b1SJohannes Berg {
261d962f9b1SJohannes Berg if (ucode_type >= IWL_UCODE_TYPE_MAX)
262d962f9b1SJohannes Berg return NULL;
263d962f9b1SJohannes Berg
264d962f9b1SJohannes Berg return &fw->img[ucode_type];
265d962f9b1SJohannes Berg }
266d962f9b1SJohannes Berg
267971cbe50SJohannes Berg u8 iwl_fw_lookup_cmd_ver(const struct iwl_fw *fw, u32 cmd_id, u8 def);
26819ff9b2cSTova Mussai
2694af11950SMordechay Goodstein u8 iwl_fw_lookup_notif_ver(const struct iwl_fw *fw, u8 grp, u8 cmd, u8 def);
27079946ee7SMordechay Goodstein const char *iwl_fw_lookup_assert_desc(u32 num);
2711db385c6SLuca Coelho
2721db385c6SLuca Coelho #define FW_SYSASSERT_CPU_MASK 0xf0000000
2731db385c6SLuca Coelho #define FW_SYSASSERT_PNVM_MISSING 0x0010070d
2741db385c6SLuca Coelho
275d962f9b1SJohannes Berg #endif /* __iwl_fw_img_h__ */
276