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