xref: /freebsd/sys/contrib/dev/iwlwifi/fw/runtime.h (revision a4128aad8503277614f2d214011ef60a19447b83)
1bfcc09ddSBjoern A. Zeeb /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2bfcc09ddSBjoern A. Zeeb /*
3bfcc09ddSBjoern A. Zeeb  * Copyright (C) 2017 Intel Deutschland GmbH
4*a4128aadSBjoern A. Zeeb  * Copyright (C) 2018-2024 Intel Corporation
5bfcc09ddSBjoern A. Zeeb  */
6bfcc09ddSBjoern A. Zeeb #ifndef __iwl_fw_runtime_h__
7bfcc09ddSBjoern A. Zeeb #define __iwl_fw_runtime_h__
8bfcc09ddSBjoern A. Zeeb 
9bfcc09ddSBjoern A. Zeeb #include "iwl-config.h"
10bfcc09ddSBjoern A. Zeeb #include "iwl-trans.h"
11bfcc09ddSBjoern A. Zeeb #include "img.h"
12bfcc09ddSBjoern A. Zeeb #include "fw/api/debug.h"
13bfcc09ddSBjoern A. Zeeb #include "fw/api/paging.h"
14bfcc09ddSBjoern A. Zeeb #include "fw/api/power.h"
15*a4128aadSBjoern A. Zeeb #include "iwl-nvm-utils.h"
16bfcc09ddSBjoern A. Zeeb #include "fw/acpi.h"
17*a4128aadSBjoern A. Zeeb #include "fw/regulatory.h"
18bfcc09ddSBjoern A. Zeeb 
19bfcc09ddSBjoern A. Zeeb struct iwl_fw_runtime_ops {
20d9836fb4SBjoern A. Zeeb 	void (*dump_start)(void *ctx);
21bfcc09ddSBjoern A. Zeeb 	void (*dump_end)(void *ctx);
22bfcc09ddSBjoern A. Zeeb 	int (*send_hcmd)(void *ctx, struct iwl_host_cmd *host_cmd);
23bfcc09ddSBjoern A. Zeeb 	bool (*d3_debug_enable)(void *ctx);
24bfcc09ddSBjoern A. Zeeb };
25bfcc09ddSBjoern A. Zeeb 
26bfcc09ddSBjoern A. Zeeb #define MAX_NUM_LMAC 2
279af1bba4SBjoern A. Zeeb #define MAX_NUM_TCM 2
289af1bba4SBjoern A. Zeeb #define MAX_NUM_RCM 2
29bfcc09ddSBjoern A. Zeeb struct iwl_fwrt_shared_mem_cfg {
30bfcc09ddSBjoern A. Zeeb 	int num_lmacs;
31bfcc09ddSBjoern A. Zeeb 	int num_txfifo_entries;
32bfcc09ddSBjoern A. Zeeb 	struct {
33bfcc09ddSBjoern A. Zeeb 		u32 txfifo_size[TX_FIFO_MAX_NUM];
34bfcc09ddSBjoern A. Zeeb 		u32 rxfifo1_size;
35bfcc09ddSBjoern A. Zeeb 	} lmac[MAX_NUM_LMAC];
36bfcc09ddSBjoern A. Zeeb 	u32 rxfifo2_size;
37bfcc09ddSBjoern A. Zeeb 	u32 rxfifo2_control_size;
38bfcc09ddSBjoern A. Zeeb 	u32 internal_txfifo_addr;
39bfcc09ddSBjoern A. Zeeb 	u32 internal_txfifo_size[TX_FIFO_INTERNAL_MAX_NUM];
40bfcc09ddSBjoern A. Zeeb };
41bfcc09ddSBjoern A. Zeeb 
42bfcc09ddSBjoern A. Zeeb #define IWL_FW_RUNTIME_DUMP_WK_NUM 5
43bfcc09ddSBjoern A. Zeeb 
44bfcc09ddSBjoern A. Zeeb /**
45bfcc09ddSBjoern A. Zeeb  * struct iwl_fwrt_dump_data - dump data
46bfcc09ddSBjoern A. Zeeb  * @trig: trigger the worker was scheduled upon
47bfcc09ddSBjoern A. Zeeb  * @fw_pkt: packet received from FW
48*a4128aadSBjoern A. Zeeb  *
49*a4128aadSBjoern A. Zeeb  * Note that the decision which part of the union is used
50*a4128aadSBjoern A. Zeeb  * is based on iwl_trans_dbg_ini_valid(): the 'trig' part
51*a4128aadSBjoern A. Zeeb  * is used if it is %true, the 'desc' part otherwise.
52bfcc09ddSBjoern A. Zeeb  */
53bfcc09ddSBjoern A. Zeeb struct iwl_fwrt_dump_data {
54bfcc09ddSBjoern A. Zeeb 	union {
55bfcc09ddSBjoern A. Zeeb 		struct {
56bfcc09ddSBjoern A. Zeeb 			struct iwl_fw_ini_trigger_tlv *trig;
57bfcc09ddSBjoern A. Zeeb 			struct iwl_rx_packet *fw_pkt;
58bfcc09ddSBjoern A. Zeeb 		};
59bfcc09ddSBjoern A. Zeeb 		struct {
60*a4128aadSBjoern A. Zeeb 			/* must be first to be same as 'trig' */
61bfcc09ddSBjoern A. Zeeb 			const struct iwl_fw_dump_desc *desc;
62bfcc09ddSBjoern A. Zeeb 			bool monitor_only;
63bfcc09ddSBjoern A. Zeeb 		};
64bfcc09ddSBjoern A. Zeeb 	};
65bfcc09ddSBjoern A. Zeeb };
66bfcc09ddSBjoern A. Zeeb 
67bfcc09ddSBjoern A. Zeeb /**
68bfcc09ddSBjoern A. Zeeb  * struct iwl_fwrt_wk_data - dump worker data struct
69bfcc09ddSBjoern A. Zeeb  * @idx: index of the worker
70bfcc09ddSBjoern A. Zeeb  * @wk: worker
71bfcc09ddSBjoern A. Zeeb  */
72bfcc09ddSBjoern A. Zeeb struct iwl_fwrt_wk_data  {
73bfcc09ddSBjoern A. Zeeb 	u8 idx;
74bfcc09ddSBjoern A. Zeeb 	struct delayed_work wk;
75bfcc09ddSBjoern A. Zeeb 	struct iwl_fwrt_dump_data dump_data;
76bfcc09ddSBjoern A. Zeeb };
77bfcc09ddSBjoern A. Zeeb 
78bfcc09ddSBjoern A. Zeeb /**
79bfcc09ddSBjoern A. Zeeb  * struct iwl_txf_iter_data - Tx fifo iterator data struct
80bfcc09ddSBjoern A. Zeeb  * @fifo: fifo number
81bfcc09ddSBjoern A. Zeeb  * @lmac: lmac number
82bfcc09ddSBjoern A. Zeeb  * @fifo_size: fifo size
83bfcc09ddSBjoern A. Zeeb  * @internal_txf: non zero if fifo is  internal Tx fifo
84bfcc09ddSBjoern A. Zeeb  */
85bfcc09ddSBjoern A. Zeeb struct iwl_txf_iter_data {
86bfcc09ddSBjoern A. Zeeb 	int fifo;
87bfcc09ddSBjoern A. Zeeb 	int lmac;
88bfcc09ddSBjoern A. Zeeb 	u32 fifo_size;
89bfcc09ddSBjoern A. Zeeb 	u8 internal_txf;
90bfcc09ddSBjoern A. Zeeb };
91bfcc09ddSBjoern A. Zeeb 
92bfcc09ddSBjoern A. Zeeb /**
93bfcc09ddSBjoern A. Zeeb  * struct iwl_fw_runtime - runtime data for firmware
94bfcc09ddSBjoern A. Zeeb  * @fw: firmware image
95bfcc09ddSBjoern A. Zeeb  * @cfg: NIC configuration
96bfcc09ddSBjoern A. Zeeb  * @dev: device pointer
97bfcc09ddSBjoern A. Zeeb  * @ops: user ops
98bfcc09ddSBjoern A. Zeeb  * @ops_ctx: user ops context
99bfcc09ddSBjoern A. Zeeb  * @fw_paging_db: paging database
100bfcc09ddSBjoern A. Zeeb  * @num_of_paging_blk: number of paging blocks
101bfcc09ddSBjoern A. Zeeb  * @num_of_pages_in_last_blk: number of pages in the last block
102bfcc09ddSBjoern A. Zeeb  * @smem_cfg: saved firmware SMEM configuration
103bfcc09ddSBjoern A. Zeeb  * @cur_fw_img: current firmware image, must be maintained by
104bfcc09ddSBjoern A. Zeeb  *	the driver by calling &iwl_fw_set_current_image()
105bfcc09ddSBjoern A. Zeeb  * @dump: debug dump data
106*a4128aadSBjoern A. Zeeb  * @uats_table: AP type table
107*a4128aadSBjoern A. Zeeb  * @uefi_tables_lock_status: The status of the WIFI GUID UEFI variables lock:
108*a4128aadSBjoern A. Zeeb  *	0: Unlocked, 1 and 2: Locked.
109*a4128aadSBjoern A. Zeeb  *	Only read the UEFI variables if locked.
110*a4128aadSBjoern A. Zeeb  * @sar_profiles: sar profiles as read from WRDS/EWRD BIOS tables
111*a4128aadSBjoern A. Zeeb  * @geo_profiles: geographic profiles as read from WGDS BIOS table
112bfcc09ddSBjoern A. Zeeb  */
113bfcc09ddSBjoern A. Zeeb struct iwl_fw_runtime {
114bfcc09ddSBjoern A. Zeeb 	struct iwl_trans *trans;
115bfcc09ddSBjoern A. Zeeb 	const struct iwl_fw *fw;
116bfcc09ddSBjoern A. Zeeb 	struct device *dev;
117bfcc09ddSBjoern A. Zeeb 
118bfcc09ddSBjoern A. Zeeb 	const struct iwl_fw_runtime_ops *ops;
119bfcc09ddSBjoern A. Zeeb 	void *ops_ctx;
120bfcc09ddSBjoern A. Zeeb 
121bfcc09ddSBjoern A. Zeeb 	const struct iwl_dump_sanitize_ops *sanitize_ops;
122bfcc09ddSBjoern A. Zeeb 	void *sanitize_ctx;
123bfcc09ddSBjoern A. Zeeb 
124bfcc09ddSBjoern A. Zeeb 	/* Paging */
125bfcc09ddSBjoern A. Zeeb 	struct iwl_fw_paging fw_paging_db[NUM_OF_FW_PAGING_BLOCKS];
126bfcc09ddSBjoern A. Zeeb 	u16 num_of_paging_blk;
127bfcc09ddSBjoern A. Zeeb 	u16 num_of_pages_in_last_blk;
128bfcc09ddSBjoern A. Zeeb 
129bfcc09ddSBjoern A. Zeeb 	enum iwl_ucode_type cur_fw_img;
130bfcc09ddSBjoern A. Zeeb 
131bfcc09ddSBjoern A. Zeeb 	/* memory configuration */
132bfcc09ddSBjoern A. Zeeb 	struct iwl_fwrt_shared_mem_cfg smem_cfg;
133bfcc09ddSBjoern A. Zeeb 
134bfcc09ddSBjoern A. Zeeb 	/* debug */
135bfcc09ddSBjoern A. Zeeb 	struct {
136bfcc09ddSBjoern A. Zeeb 		struct iwl_fwrt_wk_data wks[IWL_FW_RUNTIME_DUMP_WK_NUM];
137bfcc09ddSBjoern A. Zeeb 		unsigned long active_wks;
138bfcc09ddSBjoern A. Zeeb 
139bfcc09ddSBjoern A. Zeeb 		u8 conf;
140bfcc09ddSBjoern A. Zeeb 
141bfcc09ddSBjoern A. Zeeb 		/* ts of the beginning of a non-collect fw dbg data period */
142bfcc09ddSBjoern A. Zeeb 		unsigned long non_collect_ts_start[IWL_FW_INI_TIME_POINT_NUM];
143bfcc09ddSBjoern A. Zeeb 		u32 *d3_debug_data;
144bfcc09ddSBjoern A. Zeeb 		u32 lmac_err_id[MAX_NUM_LMAC];
1459af1bba4SBjoern A. Zeeb 		u32 tcm_err_id[MAX_NUM_TCM];
1469af1bba4SBjoern A. Zeeb 		u32 rcm_err_id[MAX_NUM_RCM];
147bfcc09ddSBjoern A. Zeeb 		u32 umac_err_id;
148bfcc09ddSBjoern A. Zeeb 
149bfcc09ddSBjoern A. Zeeb 		struct iwl_txf_iter_data txf_iter_data;
150bfcc09ddSBjoern A. Zeeb 
151bfcc09ddSBjoern A. Zeeb 		struct {
152bfcc09ddSBjoern A. Zeeb 			u8 type;
153bfcc09ddSBjoern A. Zeeb 			u8 subtype;
154bfcc09ddSBjoern A. Zeeb 			u32 lmac_major;
155bfcc09ddSBjoern A. Zeeb 			u32 lmac_minor;
156bfcc09ddSBjoern A. Zeeb 			u32 umac_major;
157bfcc09ddSBjoern A. Zeeb 			u32 umac_minor;
158bfcc09ddSBjoern A. Zeeb 		} fw_ver;
159bfcc09ddSBjoern A. Zeeb 	} dump;
160bfcc09ddSBjoern A. Zeeb 	struct {
1619af1bba4SBjoern A. Zeeb #ifdef CONFIG_IWLWIFI_DEBUGFS
162bfcc09ddSBjoern A. Zeeb 		struct delayed_work wk;
163bfcc09ddSBjoern A. Zeeb 		u32 delay;
1649af1bba4SBjoern A. Zeeb #endif
165bfcc09ddSBjoern A. Zeeb 		u64 seq;
166bfcc09ddSBjoern A. Zeeb 	} timestamp;
1679af1bba4SBjoern A. Zeeb #ifdef CONFIG_IWLWIFI_DEBUGFS
168bfcc09ddSBjoern A. Zeeb 	bool tpc_enabled;
169bfcc09ddSBjoern A. Zeeb #endif /* CONFIG_IWLWIFI_DEBUGFS */
170*a4128aadSBjoern A. Zeeb 	struct iwl_sar_profile sar_profiles[BIOS_SAR_MAX_PROFILE_NUM];
171bfcc09ddSBjoern A. Zeeb 	u8 sar_chain_a_profile;
172bfcc09ddSBjoern A. Zeeb 	u8 sar_chain_b_profile;
173*a4128aadSBjoern A. Zeeb 	u8 reduced_power_flags;
174*a4128aadSBjoern A. Zeeb 	struct iwl_geo_profile geo_profiles[BIOS_GEO_MAX_PROFILE_NUM];
175bfcc09ddSBjoern A. Zeeb 	u32 geo_rev;
176d9836fb4SBjoern A. Zeeb 	u32 geo_num_profiles;
177d9836fb4SBjoern A. Zeeb 	bool geo_enabled;
178d9836fb4SBjoern A. Zeeb 	struct iwl_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS];
179d9836fb4SBjoern A. Zeeb 	u32 ppag_flags;
180*a4128aadSBjoern A. Zeeb 	u8 ppag_ver;
181d9836fb4SBjoern A. Zeeb 	struct iwl_sar_offset_mapping_cmd sgom_table;
182d9836fb4SBjoern A. Zeeb 	bool sgom_enabled;
183*a4128aadSBjoern A. Zeeb 	struct iwl_mcc_allowed_ap_type_cmd uats_table;
184*a4128aadSBjoern A. Zeeb 	u8 uefi_tables_lock_status;
185bfcc09ddSBjoern A. Zeeb };
186bfcc09ddSBjoern A. Zeeb 
187bfcc09ddSBjoern A. Zeeb void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
188bfcc09ddSBjoern A. Zeeb 			const struct iwl_fw *fw,
189bfcc09ddSBjoern A. Zeeb 			const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
190bfcc09ddSBjoern A. Zeeb 			const struct iwl_dump_sanitize_ops *sanitize_ops,
191bfcc09ddSBjoern A. Zeeb 			void *sanitize_ctx,
192bfcc09ddSBjoern A. Zeeb 			struct dentry *dbgfs_dir);
193bfcc09ddSBjoern A. Zeeb 
194bfcc09ddSBjoern A. Zeeb static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt)
195bfcc09ddSBjoern A. Zeeb {
196bfcc09ddSBjoern A. Zeeb 	int i;
197bfcc09ddSBjoern A. Zeeb 
198bfcc09ddSBjoern A. Zeeb 	kfree(fwrt->dump.d3_debug_data);
199bfcc09ddSBjoern A. Zeeb 	fwrt->dump.d3_debug_data = NULL;
200bfcc09ddSBjoern A. Zeeb 
201bfcc09ddSBjoern A. Zeeb 	iwl_dbg_tlv_del_timers(fwrt->trans);
202bfcc09ddSBjoern A. Zeeb 	for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++)
203bfcc09ddSBjoern A. Zeeb 		cancel_delayed_work_sync(&fwrt->dump.wks[i].wk);
204bfcc09ddSBjoern A. Zeeb }
205bfcc09ddSBjoern A. Zeeb 
206bfcc09ddSBjoern A. Zeeb void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
207bfcc09ddSBjoern A. Zeeb 
208bfcc09ddSBjoern A. Zeeb void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt);
209bfcc09ddSBjoern A. Zeeb 
210bfcc09ddSBjoern A. Zeeb static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt,
211bfcc09ddSBjoern A. Zeeb 					    enum iwl_ucode_type cur_fw_img)
212bfcc09ddSBjoern A. Zeeb {
213bfcc09ddSBjoern A. Zeeb 	fwrt->cur_fw_img = cur_fw_img;
214bfcc09ddSBjoern A. Zeeb }
215bfcc09ddSBjoern A. Zeeb 
216bfcc09ddSBjoern A. Zeeb int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type);
217bfcc09ddSBjoern A. Zeeb void iwl_free_fw_paging(struct iwl_fw_runtime *fwrt);
218bfcc09ddSBjoern A. Zeeb 
219bfcc09ddSBjoern A. Zeeb void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt);
220bfcc09ddSBjoern A. Zeeb int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt);
221bfcc09ddSBjoern A. Zeeb int iwl_configure_rxq(struct iwl_fw_runtime *fwrt);
222bfcc09ddSBjoern A. Zeeb 
223bfcc09ddSBjoern A. Zeeb #endif /* __iwl_fw_runtime_h__ */
224