162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2017 Intel Deutschland GmbH
462306a36Sopenharmony_ci * Copyright (C) 2018-2023 Intel Corporation
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef __iwl_fw_runtime_h__
762306a36Sopenharmony_ci#define __iwl_fw_runtime_h__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include "iwl-config.h"
1062306a36Sopenharmony_ci#include "iwl-trans.h"
1162306a36Sopenharmony_ci#include "img.h"
1262306a36Sopenharmony_ci#include "fw/api/debug.h"
1362306a36Sopenharmony_ci#include "fw/api/paging.h"
1462306a36Sopenharmony_ci#include "fw/api/power.h"
1562306a36Sopenharmony_ci#include "iwl-eeprom-parse.h"
1662306a36Sopenharmony_ci#include "fw/acpi.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistruct iwl_fw_runtime_ops {
1962306a36Sopenharmony_ci	void (*dump_start)(void *ctx);
2062306a36Sopenharmony_ci	void (*dump_end)(void *ctx);
2162306a36Sopenharmony_ci	bool (*fw_running)(void *ctx);
2262306a36Sopenharmony_ci	int (*send_hcmd)(void *ctx, struct iwl_host_cmd *host_cmd);
2362306a36Sopenharmony_ci	bool (*d3_debug_enable)(void *ctx);
2462306a36Sopenharmony_ci};
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define MAX_NUM_LMAC 2
2762306a36Sopenharmony_ci#define MAX_NUM_TCM 2
2862306a36Sopenharmony_ci#define MAX_NUM_RCM 2
2962306a36Sopenharmony_cistruct iwl_fwrt_shared_mem_cfg {
3062306a36Sopenharmony_ci	int num_lmacs;
3162306a36Sopenharmony_ci	int num_txfifo_entries;
3262306a36Sopenharmony_ci	struct {
3362306a36Sopenharmony_ci		u32 txfifo_size[TX_FIFO_MAX_NUM];
3462306a36Sopenharmony_ci		u32 rxfifo1_size;
3562306a36Sopenharmony_ci	} lmac[MAX_NUM_LMAC];
3662306a36Sopenharmony_ci	u32 rxfifo2_size;
3762306a36Sopenharmony_ci	u32 rxfifo2_control_size;
3862306a36Sopenharmony_ci	u32 internal_txfifo_addr;
3962306a36Sopenharmony_ci	u32 internal_txfifo_size[TX_FIFO_INTERNAL_MAX_NUM];
4062306a36Sopenharmony_ci};
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#define IWL_FW_RUNTIME_DUMP_WK_NUM 5
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/**
4562306a36Sopenharmony_ci * struct iwl_fwrt_dump_data - dump data
4662306a36Sopenharmony_ci * @trig: trigger the worker was scheduled upon
4762306a36Sopenharmony_ci * @fw_pkt: packet received from FW
4862306a36Sopenharmony_ci */
4962306a36Sopenharmony_cistruct iwl_fwrt_dump_data {
5062306a36Sopenharmony_ci	union {
5162306a36Sopenharmony_ci		struct {
5262306a36Sopenharmony_ci			struct iwl_fw_ini_trigger_tlv *trig;
5362306a36Sopenharmony_ci			struct iwl_rx_packet *fw_pkt;
5462306a36Sopenharmony_ci		};
5562306a36Sopenharmony_ci		struct {
5662306a36Sopenharmony_ci			const struct iwl_fw_dump_desc *desc;
5762306a36Sopenharmony_ci			bool monitor_only;
5862306a36Sopenharmony_ci		};
5962306a36Sopenharmony_ci	};
6062306a36Sopenharmony_ci};
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci/**
6362306a36Sopenharmony_ci * struct iwl_fwrt_wk_data - dump worker data struct
6462306a36Sopenharmony_ci * @idx: index of the worker
6562306a36Sopenharmony_ci * @wk: worker
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_cistruct iwl_fwrt_wk_data  {
6862306a36Sopenharmony_ci	u8 idx;
6962306a36Sopenharmony_ci	struct delayed_work wk;
7062306a36Sopenharmony_ci	struct iwl_fwrt_dump_data dump_data;
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/**
7462306a36Sopenharmony_ci * struct iwl_txf_iter_data - Tx fifo iterator data struct
7562306a36Sopenharmony_ci * @fifo: fifo number
7662306a36Sopenharmony_ci * @lmac: lmac number
7762306a36Sopenharmony_ci * @fifo_size: fifo size
7862306a36Sopenharmony_ci * @internal_txf: non zero if fifo is  internal Tx fifo
7962306a36Sopenharmony_ci */
8062306a36Sopenharmony_cistruct iwl_txf_iter_data {
8162306a36Sopenharmony_ci	int fifo;
8262306a36Sopenharmony_ci	int lmac;
8362306a36Sopenharmony_ci	u32 fifo_size;
8462306a36Sopenharmony_ci	u8 internal_txf;
8562306a36Sopenharmony_ci};
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci/**
8862306a36Sopenharmony_ci * struct iwl_fw_runtime - runtime data for firmware
8962306a36Sopenharmony_ci * @fw: firmware image
9062306a36Sopenharmony_ci * @cfg: NIC configuration
9162306a36Sopenharmony_ci * @dev: device pointer
9262306a36Sopenharmony_ci * @ops: user ops
9362306a36Sopenharmony_ci * @ops_ctx: user ops context
9462306a36Sopenharmony_ci * @fw_paging_db: paging database
9562306a36Sopenharmony_ci * @num_of_paging_blk: number of paging blocks
9662306a36Sopenharmony_ci * @num_of_pages_in_last_blk: number of pages in the last block
9762306a36Sopenharmony_ci * @smem_cfg: saved firmware SMEM configuration
9862306a36Sopenharmony_ci * @cur_fw_img: current firmware image, must be maintained by
9962306a36Sopenharmony_ci *	the driver by calling &iwl_fw_set_current_image()
10062306a36Sopenharmony_ci * @dump: debug dump data
10162306a36Sopenharmony_ci */
10262306a36Sopenharmony_cistruct iwl_fw_runtime {
10362306a36Sopenharmony_ci	struct iwl_trans *trans;
10462306a36Sopenharmony_ci	const struct iwl_fw *fw;
10562306a36Sopenharmony_ci	struct device *dev;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	const struct iwl_fw_runtime_ops *ops;
10862306a36Sopenharmony_ci	void *ops_ctx;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	const struct iwl_dump_sanitize_ops *sanitize_ops;
11162306a36Sopenharmony_ci	void *sanitize_ctx;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	/* Paging */
11462306a36Sopenharmony_ci	struct iwl_fw_paging fw_paging_db[NUM_OF_FW_PAGING_BLOCKS];
11562306a36Sopenharmony_ci	u16 num_of_paging_blk;
11662306a36Sopenharmony_ci	u16 num_of_pages_in_last_blk;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	enum iwl_ucode_type cur_fw_img;
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	/* memory configuration */
12162306a36Sopenharmony_ci	struct iwl_fwrt_shared_mem_cfg smem_cfg;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	/* debug */
12462306a36Sopenharmony_ci	struct {
12562306a36Sopenharmony_ci		struct iwl_fwrt_wk_data wks[IWL_FW_RUNTIME_DUMP_WK_NUM];
12662306a36Sopenharmony_ci		unsigned long active_wks;
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci		u8 conf;
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci		/* ts of the beginning of a non-collect fw dbg data period */
13162306a36Sopenharmony_ci		unsigned long non_collect_ts_start[IWL_FW_INI_TIME_POINT_NUM];
13262306a36Sopenharmony_ci		u32 *d3_debug_data;
13362306a36Sopenharmony_ci		u32 lmac_err_id[MAX_NUM_LMAC];
13462306a36Sopenharmony_ci		u32 tcm_err_id[MAX_NUM_TCM];
13562306a36Sopenharmony_ci		u32 rcm_err_id[MAX_NUM_RCM];
13662306a36Sopenharmony_ci		u32 umac_err_id;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci		struct iwl_txf_iter_data txf_iter_data;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci		struct {
14162306a36Sopenharmony_ci			u8 type;
14262306a36Sopenharmony_ci			u8 subtype;
14362306a36Sopenharmony_ci			u32 lmac_major;
14462306a36Sopenharmony_ci			u32 lmac_minor;
14562306a36Sopenharmony_ci			u32 umac_major;
14662306a36Sopenharmony_ci			u32 umac_minor;
14762306a36Sopenharmony_ci		} fw_ver;
14862306a36Sopenharmony_ci	} dump;
14962306a36Sopenharmony_ci	struct {
15062306a36Sopenharmony_ci#ifdef CONFIG_IWLWIFI_DEBUGFS
15162306a36Sopenharmony_ci		struct delayed_work wk;
15262306a36Sopenharmony_ci		u32 delay;
15362306a36Sopenharmony_ci#endif
15462306a36Sopenharmony_ci		u64 seq;
15562306a36Sopenharmony_ci	} timestamp;
15662306a36Sopenharmony_ci#ifdef CONFIG_IWLWIFI_DEBUGFS
15762306a36Sopenharmony_ci	bool tpc_enabled;
15862306a36Sopenharmony_ci#endif /* CONFIG_IWLWIFI_DEBUGFS */
15962306a36Sopenharmony_ci#ifdef CONFIG_ACPI
16062306a36Sopenharmony_ci	struct iwl_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
16162306a36Sopenharmony_ci	u8 sar_chain_a_profile;
16262306a36Sopenharmony_ci	u8 sar_chain_b_profile;
16362306a36Sopenharmony_ci	struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES_REV3];
16462306a36Sopenharmony_ci	u32 geo_rev;
16562306a36Sopenharmony_ci	u32 geo_num_profiles;
16662306a36Sopenharmony_ci	bool geo_enabled;
16762306a36Sopenharmony_ci	struct iwl_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS];
16862306a36Sopenharmony_ci	u32 ppag_flags;
16962306a36Sopenharmony_ci	u32 ppag_ver;
17062306a36Sopenharmony_ci	bool ppag_table_valid;
17162306a36Sopenharmony_ci	struct iwl_sar_offset_mapping_cmd sgom_table;
17262306a36Sopenharmony_ci	bool sgom_enabled;
17362306a36Sopenharmony_ci	u8 reduced_power_flags;
17462306a36Sopenharmony_ci#endif
17562306a36Sopenharmony_ci};
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_civoid iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
17862306a36Sopenharmony_ci			const struct iwl_fw *fw,
17962306a36Sopenharmony_ci			const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
18062306a36Sopenharmony_ci			const struct iwl_dump_sanitize_ops *sanitize_ops,
18162306a36Sopenharmony_ci			void *sanitize_ctx,
18262306a36Sopenharmony_ci			struct dentry *dbgfs_dir);
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_cistatic inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	int i;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	kfree(fwrt->dump.d3_debug_data);
18962306a36Sopenharmony_ci	fwrt->dump.d3_debug_data = NULL;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	iwl_dbg_tlv_del_timers(fwrt->trans);
19262306a36Sopenharmony_ci	for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++)
19362306a36Sopenharmony_ci		cancel_delayed_work_sync(&fwrt->dump.wks[i].wk);
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_civoid iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_civoid iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt);
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistatic inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt,
20162306a36Sopenharmony_ci					    enum iwl_ucode_type cur_fw_img)
20262306a36Sopenharmony_ci{
20362306a36Sopenharmony_ci	fwrt->cur_fw_img = cur_fw_img;
20462306a36Sopenharmony_ci}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ciint iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type);
20762306a36Sopenharmony_civoid iwl_free_fw_paging(struct iwl_fw_runtime *fwrt);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_civoid iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt);
21062306a36Sopenharmony_ciint iwl_set_soc_latency(struct iwl_fw_runtime *fwrt);
21162306a36Sopenharmony_ciint iwl_configure_rxq(struct iwl_fw_runtime *fwrt);
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci#endif /* __iwl_fw_runtime_h__ */
214