xref: /freebsd/sys/contrib/dev/iwlwifi/fw/img.h (revision 9af1bba4)
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