xref: /freebsd/sys/contrib/dev/iwlwifi/fw/runtime.h (revision 9af1bba44e1ce9b0296ae56760b564d67ab7a1cf)
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*9af1bba4SBjoern A. Zeeb  * Copyright (C) 2018-2023 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"
15bfcc09ddSBjoern A. Zeeb #include "iwl-eeprom-parse.h"
16bfcc09ddSBjoern A. Zeeb #include "fw/acpi.h"
17bfcc09ddSBjoern A. Zeeb 
18bfcc09ddSBjoern A. Zeeb struct iwl_fw_runtime_ops {
19d9836fb4SBjoern A. Zeeb 	void (*dump_start)(void *ctx);
20bfcc09ddSBjoern A. Zeeb 	void (*dump_end)(void *ctx);
21bfcc09ddSBjoern A. Zeeb 	bool (*fw_running)(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
27*9af1bba4SBjoern A. Zeeb #define MAX_NUM_TCM 2
28*9af1bba4SBjoern 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
48bfcc09ddSBjoern A. Zeeb  */
49bfcc09ddSBjoern A. Zeeb struct iwl_fwrt_dump_data {
50bfcc09ddSBjoern A. Zeeb 	union {
51bfcc09ddSBjoern A. Zeeb 		struct {
52bfcc09ddSBjoern A. Zeeb 			struct iwl_fw_ini_trigger_tlv *trig;
53bfcc09ddSBjoern A. Zeeb 			struct iwl_rx_packet *fw_pkt;
54bfcc09ddSBjoern A. Zeeb 		};
55bfcc09ddSBjoern A. Zeeb 		struct {
56bfcc09ddSBjoern A. Zeeb 			const struct iwl_fw_dump_desc *desc;
57bfcc09ddSBjoern A. Zeeb 			bool monitor_only;
58bfcc09ddSBjoern A. Zeeb 		};
59bfcc09ddSBjoern A. Zeeb 	};
60bfcc09ddSBjoern A. Zeeb };
61bfcc09ddSBjoern A. Zeeb 
62bfcc09ddSBjoern A. Zeeb /**
63bfcc09ddSBjoern A. Zeeb  * struct iwl_fwrt_wk_data - dump worker data struct
64bfcc09ddSBjoern A. Zeeb  * @idx: index of the worker
65bfcc09ddSBjoern A. Zeeb  * @wk: worker
66bfcc09ddSBjoern A. Zeeb  */
67bfcc09ddSBjoern A. Zeeb struct iwl_fwrt_wk_data  {
68bfcc09ddSBjoern A. Zeeb 	u8 idx;
69bfcc09ddSBjoern A. Zeeb 	struct delayed_work wk;
70bfcc09ddSBjoern A. Zeeb 	struct iwl_fwrt_dump_data dump_data;
71bfcc09ddSBjoern A. Zeeb };
72bfcc09ddSBjoern A. Zeeb 
73bfcc09ddSBjoern A. Zeeb /**
74bfcc09ddSBjoern A. Zeeb  * struct iwl_txf_iter_data - Tx fifo iterator data struct
75bfcc09ddSBjoern A. Zeeb  * @fifo: fifo number
76bfcc09ddSBjoern A. Zeeb  * @lmac: lmac number
77bfcc09ddSBjoern A. Zeeb  * @fifo_size: fifo size
78bfcc09ddSBjoern A. Zeeb  * @internal_txf: non zero if fifo is  internal Tx fifo
79bfcc09ddSBjoern A. Zeeb  */
80bfcc09ddSBjoern A. Zeeb struct iwl_txf_iter_data {
81bfcc09ddSBjoern A. Zeeb 	int fifo;
82bfcc09ddSBjoern A. Zeeb 	int lmac;
83bfcc09ddSBjoern A. Zeeb 	u32 fifo_size;
84bfcc09ddSBjoern A. Zeeb 	u8 internal_txf;
85bfcc09ddSBjoern A. Zeeb };
86bfcc09ddSBjoern A. Zeeb 
87bfcc09ddSBjoern A. Zeeb /**
88bfcc09ddSBjoern A. Zeeb  * struct iwl_fw_runtime - runtime data for firmware
89bfcc09ddSBjoern A. Zeeb  * @fw: firmware image
90bfcc09ddSBjoern A. Zeeb  * @cfg: NIC configuration
91bfcc09ddSBjoern A. Zeeb  * @dev: device pointer
92bfcc09ddSBjoern A. Zeeb  * @ops: user ops
93bfcc09ddSBjoern A. Zeeb  * @ops_ctx: user ops context
94bfcc09ddSBjoern A. Zeeb  * @fw_paging_db: paging database
95bfcc09ddSBjoern A. Zeeb  * @num_of_paging_blk: number of paging blocks
96bfcc09ddSBjoern A. Zeeb  * @num_of_pages_in_last_blk: number of pages in the last block
97bfcc09ddSBjoern A. Zeeb  * @smem_cfg: saved firmware SMEM configuration
98bfcc09ddSBjoern A. Zeeb  * @cur_fw_img: current firmware image, must be maintained by
99bfcc09ddSBjoern A. Zeeb  *	the driver by calling &iwl_fw_set_current_image()
100bfcc09ddSBjoern A. Zeeb  * @dump: debug dump data
101bfcc09ddSBjoern A. Zeeb  */
102bfcc09ddSBjoern A. Zeeb struct iwl_fw_runtime {
103bfcc09ddSBjoern A. Zeeb 	struct iwl_trans *trans;
104bfcc09ddSBjoern A. Zeeb 	const struct iwl_fw *fw;
105bfcc09ddSBjoern A. Zeeb 	struct device *dev;
106bfcc09ddSBjoern A. Zeeb 
107bfcc09ddSBjoern A. Zeeb 	const struct iwl_fw_runtime_ops *ops;
108bfcc09ddSBjoern A. Zeeb 	void *ops_ctx;
109bfcc09ddSBjoern A. Zeeb 
110bfcc09ddSBjoern A. Zeeb 	const struct iwl_dump_sanitize_ops *sanitize_ops;
111bfcc09ddSBjoern A. Zeeb 	void *sanitize_ctx;
112bfcc09ddSBjoern A. Zeeb 
113bfcc09ddSBjoern A. Zeeb 	/* Paging */
114bfcc09ddSBjoern A. Zeeb 	struct iwl_fw_paging fw_paging_db[NUM_OF_FW_PAGING_BLOCKS];
115bfcc09ddSBjoern A. Zeeb 	u16 num_of_paging_blk;
116bfcc09ddSBjoern A. Zeeb 	u16 num_of_pages_in_last_blk;
117bfcc09ddSBjoern A. Zeeb 
118bfcc09ddSBjoern A. Zeeb 	enum iwl_ucode_type cur_fw_img;
119bfcc09ddSBjoern A. Zeeb 
120bfcc09ddSBjoern A. Zeeb 	/* memory configuration */
121bfcc09ddSBjoern A. Zeeb 	struct iwl_fwrt_shared_mem_cfg smem_cfg;
122bfcc09ddSBjoern A. Zeeb 
123bfcc09ddSBjoern A. Zeeb 	/* debug */
124bfcc09ddSBjoern A. Zeeb 	struct {
125bfcc09ddSBjoern A. Zeeb 		struct iwl_fwrt_wk_data wks[IWL_FW_RUNTIME_DUMP_WK_NUM];
126bfcc09ddSBjoern A. Zeeb 		unsigned long active_wks;
127bfcc09ddSBjoern A. Zeeb 
128bfcc09ddSBjoern A. Zeeb 		u8 conf;
129bfcc09ddSBjoern A. Zeeb 
130bfcc09ddSBjoern A. Zeeb 		/* ts of the beginning of a non-collect fw dbg data period */
131bfcc09ddSBjoern A. Zeeb 		unsigned long non_collect_ts_start[IWL_FW_INI_TIME_POINT_NUM];
132bfcc09ddSBjoern A. Zeeb 		u32 *d3_debug_data;
133bfcc09ddSBjoern A. Zeeb 		u32 lmac_err_id[MAX_NUM_LMAC];
134*9af1bba4SBjoern A. Zeeb 		u32 tcm_err_id[MAX_NUM_TCM];
135*9af1bba4SBjoern A. Zeeb 		u32 rcm_err_id[MAX_NUM_RCM];
136bfcc09ddSBjoern A. Zeeb 		u32 umac_err_id;
137bfcc09ddSBjoern A. Zeeb 
138bfcc09ddSBjoern A. Zeeb 		struct iwl_txf_iter_data txf_iter_data;
139bfcc09ddSBjoern A. Zeeb 
140bfcc09ddSBjoern A. Zeeb 		struct {
141bfcc09ddSBjoern A. Zeeb 			u8 type;
142bfcc09ddSBjoern A. Zeeb 			u8 subtype;
143bfcc09ddSBjoern A. Zeeb 			u32 lmac_major;
144bfcc09ddSBjoern A. Zeeb 			u32 lmac_minor;
145bfcc09ddSBjoern A. Zeeb 			u32 umac_major;
146bfcc09ddSBjoern A. Zeeb 			u32 umac_minor;
147bfcc09ddSBjoern A. Zeeb 		} fw_ver;
148bfcc09ddSBjoern A. Zeeb 	} dump;
149bfcc09ddSBjoern A. Zeeb 	struct {
150*9af1bba4SBjoern A. Zeeb #ifdef CONFIG_IWLWIFI_DEBUGFS
151bfcc09ddSBjoern A. Zeeb 		struct delayed_work wk;
152bfcc09ddSBjoern A. Zeeb 		u32 delay;
153*9af1bba4SBjoern A. Zeeb #endif
154bfcc09ddSBjoern A. Zeeb 		u64 seq;
155bfcc09ddSBjoern A. Zeeb 	} timestamp;
156*9af1bba4SBjoern A. Zeeb #ifdef CONFIG_IWLWIFI_DEBUGFS
157bfcc09ddSBjoern A. Zeeb 	bool tpc_enabled;
158bfcc09ddSBjoern A. Zeeb #endif /* CONFIG_IWLWIFI_DEBUGFS */
159bfcc09ddSBjoern A. Zeeb #ifdef CONFIG_ACPI
160bfcc09ddSBjoern A. Zeeb 	struct iwl_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
161bfcc09ddSBjoern A. Zeeb 	u8 sar_chain_a_profile;
162bfcc09ddSBjoern A. Zeeb 	u8 sar_chain_b_profile;
163bfcc09ddSBjoern A. Zeeb 	struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES_REV3];
164bfcc09ddSBjoern A. Zeeb 	u32 geo_rev;
165d9836fb4SBjoern A. Zeeb 	u32 geo_num_profiles;
166d9836fb4SBjoern A. Zeeb 	bool geo_enabled;
167d9836fb4SBjoern A. Zeeb 	struct iwl_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS];
168d9836fb4SBjoern A. Zeeb 	u32 ppag_flags;
169bfcc09ddSBjoern A. Zeeb 	u32 ppag_ver;
170*9af1bba4SBjoern A. Zeeb 	bool ppag_table_valid;
171d9836fb4SBjoern A. Zeeb 	struct iwl_sar_offset_mapping_cmd sgom_table;
172d9836fb4SBjoern A. Zeeb 	bool sgom_enabled;
173fac1f593SBjoern A. Zeeb 	u8 reduced_power_flags;
174bfcc09ddSBjoern A. Zeeb #endif
175bfcc09ddSBjoern A. Zeeb };
176bfcc09ddSBjoern A. Zeeb 
177bfcc09ddSBjoern A. Zeeb void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
178bfcc09ddSBjoern A. Zeeb 			const struct iwl_fw *fw,
179bfcc09ddSBjoern A. Zeeb 			const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
180bfcc09ddSBjoern A. Zeeb 			const struct iwl_dump_sanitize_ops *sanitize_ops,
181bfcc09ddSBjoern A. Zeeb 			void *sanitize_ctx,
182bfcc09ddSBjoern A. Zeeb 			struct dentry *dbgfs_dir);
183bfcc09ddSBjoern A. Zeeb 
184bfcc09ddSBjoern A. Zeeb static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt)
185bfcc09ddSBjoern A. Zeeb {
186bfcc09ddSBjoern A. Zeeb 	int i;
187bfcc09ddSBjoern A. Zeeb 
188bfcc09ddSBjoern A. Zeeb 	kfree(fwrt->dump.d3_debug_data);
189bfcc09ddSBjoern A. Zeeb 	fwrt->dump.d3_debug_data = NULL;
190bfcc09ddSBjoern A. Zeeb 
191bfcc09ddSBjoern A. Zeeb 	iwl_dbg_tlv_del_timers(fwrt->trans);
192bfcc09ddSBjoern A. Zeeb 	for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++)
193bfcc09ddSBjoern A. Zeeb 		cancel_delayed_work_sync(&fwrt->dump.wks[i].wk);
194bfcc09ddSBjoern A. Zeeb }
195bfcc09ddSBjoern A. Zeeb 
196bfcc09ddSBjoern A. Zeeb void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
197bfcc09ddSBjoern A. Zeeb 
198bfcc09ddSBjoern A. Zeeb void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt);
199bfcc09ddSBjoern A. Zeeb 
200bfcc09ddSBjoern A. Zeeb static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt,
201bfcc09ddSBjoern A. Zeeb 					    enum iwl_ucode_type cur_fw_img)
202bfcc09ddSBjoern A. Zeeb {
203bfcc09ddSBjoern A. Zeeb 	fwrt->cur_fw_img = cur_fw_img;
204bfcc09ddSBjoern A. Zeeb }
205bfcc09ddSBjoern A. Zeeb 
206bfcc09ddSBjoern A. Zeeb int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type);
207bfcc09ddSBjoern A. Zeeb void iwl_free_fw_paging(struct iwl_fw_runtime *fwrt);
208bfcc09ddSBjoern A. Zeeb 
209bfcc09ddSBjoern A. Zeeb void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt);
210bfcc09ddSBjoern A. Zeeb int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt);
211bfcc09ddSBjoern A. Zeeb int iwl_configure_rxq(struct iwl_fw_runtime *fwrt);
212bfcc09ddSBjoern A. Zeeb 
213bfcc09ddSBjoern A. Zeeb #endif /* __iwl_fw_runtime_h__ */
214