Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54a9c899 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "icnss2: Add support for MHI state info"

parents 5ab7307c 578ed3c9
Loading
Loading
Loading
Loading
+120 −27
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2021, The Linux Foundation. All rights reserved. */

#include "wlan_firmware_service_v01.h"
#include <linux/module.h>
@@ -502,7 +502,8 @@ static struct qmi_elem_info wlfw_m3_segment_info_s_v01_ei[] = {
		.elem_size      = sizeof(enum wlfw_m3_segment_type_v01),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0,
		.offset         = offsetof(struct wlfw_m3_segment_info_s_v01,
		.offset         = offsetof(struct
					   wlfw_m3_segment_info_s_v01,
					   type),
	},
	{
@@ -511,7 +512,8 @@ static struct qmi_elem_info wlfw_m3_segment_info_s_v01_ei[] = {
		.elem_size      = sizeof(u64),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0,
		.offset         = offsetof(struct wlfw_m3_segment_info_s_v01,
		.offset         = offsetof(struct
					   wlfw_m3_segment_info_s_v01,
					   addr),
	},
	{
@@ -520,7 +522,8 @@ static struct qmi_elem_info wlfw_m3_segment_info_s_v01_ei[] = {
		.elem_size      = sizeof(u64),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0,
		.offset         = offsetof(struct wlfw_m3_segment_info_s_v01,
		.offset         = offsetof(struct
					   wlfw_m3_segment_info_s_v01,
					   size),
	},
	{
@@ -529,7 +532,8 @@ static struct qmi_elem_info wlfw_m3_segment_info_s_v01_ei[] = {
		.elem_size      = sizeof(char),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0,
		.offset         = offsetof(struct wlfw_m3_segment_info_s_v01,
		.offset         = offsetof(struct
					   wlfw_m3_segment_info_s_v01,
					   name),
	},
	{
@@ -546,7 +550,8 @@ static struct qmi_elem_info wlfw_dev_mem_info_s_v01_ei[] = {
		.elem_size      = sizeof(u64),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0,
		.offset         = offsetof(struct wlfw_dev_mem_info_s_v01,
		.offset         = offsetof(struct
					   wlfw_dev_mem_info_s_v01,
					   start),
	},
	{
@@ -555,7 +560,8 @@ static struct qmi_elem_info wlfw_dev_mem_info_s_v01_ei[] = {
		.elem_size      = sizeof(u64),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0,
		.offset         = offsetof(struct wlfw_dev_mem_info_s_v01,
		.offset         = offsetof(struct
					   wlfw_dev_mem_info_s_v01,
					   size),
	},
	{
@@ -952,8 +958,8 @@ struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[] = {
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x23,
		.offset         =
		offsetof(struct wlfw_ind_register_req_msg_v01,
		.offset         = offsetof(struct
					   wlfw_ind_register_req_msg_v01,
					   m3_dump_upload_segments_req_enable_valid),
	},
	{
@@ -962,7 +968,8 @@ struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[] = {
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x23,
		.offset         = offsetof(struct wlfw_ind_register_req_msg_v01,
		.offset         = offsetof(struct
					   wlfw_ind_register_req_msg_v01,
					   m3_dump_upload_segments_req_enable),
	},
	{
@@ -1695,7 +1702,8 @@ struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[] = {
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x1C,
		.offset         = offsetof(struct wlfw_cap_resp_msg_v01,
		.offset         = offsetof(struct
					   wlfw_cap_resp_msg_v01,
					   dev_mem_info_valid),
	},
	{
@@ -1704,7 +1712,8 @@ struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[] = {
		.elem_size      = sizeof(struct wlfw_dev_mem_info_s_v01),
		.array_type       = STATIC_ARRAY,
		.tlv_type       = 0x1C,
		.offset         = offsetof(struct wlfw_cap_resp_msg_v01,
		.offset         = offsetof(struct
					   wlfw_cap_resp_msg_v01,
					   dev_mem_info),
		.ei_array      = wlfw_dev_mem_info_s_v01_ei,
	},
@@ -1966,6 +1975,26 @@ struct qmi_elem_info wlfw_cal_report_req_msg_v01_ei[] = {
					   wlfw_cal_report_req_msg_v01,
					   cal_remove_supported),
	},
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x12,
		.offset         = offsetof(struct
					   wlfw_cal_report_req_msg_v01,
					   cal_file_download_size_valid),
	},
	{
		.data_type      = QMI_UNSIGNED_8_BYTE,
		.elem_len       = 1,
		.elem_size      = sizeof(u64),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x12,
		.offset         = offsetof(struct
					   wlfw_cal_report_req_msg_v01,
					   cal_file_download_size),
	},
	{
		.data_type      = QMI_EOTI,
		.array_type       = NO_ARRAY,
@@ -3320,7 +3349,8 @@ struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = {
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct wlfw_fw_init_done_ind_msg_v01,
		.offset         = offsetof(struct
					   wlfw_fw_init_done_ind_msg_v01,
					   hang_data_addr_offset_valid),
	},
	{
@@ -3329,7 +3359,8 @@ struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = {
		.elem_size      = sizeof(u32),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct wlfw_fw_init_done_ind_msg_v01,
		.offset         = offsetof(struct
					   wlfw_fw_init_done_ind_msg_v01,
					   hang_data_addr_offset),
	},
	{
@@ -3338,7 +3369,8 @@ struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = {
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x11,
		.offset         = offsetof(struct wlfw_fw_init_done_ind_msg_v01,
		.offset         = offsetof(struct
					   wlfw_fw_init_done_ind_msg_v01,
					   hang_data_length_valid),
	},
	{
@@ -3347,7 +3379,8 @@ struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = {
		.elem_size      = sizeof(u16),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x11,
		.offset         = offsetof(struct wlfw_fw_init_done_ind_msg_v01,
		.offset         = offsetof(struct
					   wlfw_fw_init_done_ind_msg_v01,
					   hang_data_length),
	},
	{
@@ -3634,6 +3667,26 @@ struct qmi_elem_info wlfw_xo_cal_ind_msg_v01_ei[] = {
EXPORT_SYMBOL(wlfw_xo_cal_ind_msg_v01_ei);

struct qmi_elem_info wlfw_cal_done_ind_msg_v01_ei[] = {
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct
					   wlfw_cal_done_ind_msg_v01,
					   cal_file_upload_size_valid),
	},
	{
		.data_type      = QMI_UNSIGNED_8_BYTE,
		.elem_len       = 1,
		.elem_size      = sizeof(u64),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct
					   wlfw_cal_done_ind_msg_v01,
					   cal_file_upload_size),
	},
	{
		.data_type      = QMI_EOTI,
		.array_type       = NO_ARRAY,
@@ -4704,6 +4757,46 @@ struct qmi_elem_info wlfw_device_info_resp_msg_v01_ei[] = {
					   wlfw_device_info_resp_msg_v01,
					   bar_size),
	},
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x12,
		.offset         = offsetof(struct
					   wlfw_device_info_resp_msg_v01,
					   mhi_state_info_addr_valid),
	},
	{
		.data_type      = QMI_UNSIGNED_8_BYTE,
		.elem_len       = 1,
		.elem_size      = sizeof(u64),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x12,
		.offset         = offsetof(struct
					   wlfw_device_info_resp_msg_v01,
					   mhi_state_info_addr),
	},
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x13,
		.offset         = offsetof(struct
					   wlfw_device_info_resp_msg_v01,
					   mhi_state_info_size_valid),
	},
	{
		.data_type      = QMI_UNSIGNED_4_BYTE,
		.elem_len       = 1,
		.elem_size      = sizeof(u32),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x13,
		.offset         = offsetof(struct
					   wlfw_device_info_resp_msg_v01,
					   mhi_state_info_size),
	},
	{
		.data_type      = QMI_EOTI,
		.array_type       = NO_ARRAY,
@@ -5082,8 +5175,8 @@ struct qmi_elem_info wlfw_m3_dump_upload_segments_req_ind_msg_v01_ei[] = {
		.elem_size      = sizeof(u32),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x01,
		.offset         =
		offsetof(struct wlfw_m3_dump_upload_segments_req_ind_msg_v01,
		.offset         = offsetof(struct
					   wlfw_m3_dump_upload_segments_req_ind_msg_v01,
					   pdev_id),
	},
	{
@@ -5092,8 +5185,8 @@ struct qmi_elem_info wlfw_m3_dump_upload_segments_req_ind_msg_v01_ei[] = {
		.elem_size      = sizeof(u32),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x02,
		.offset         =
		offsetof(struct wlfw_m3_dump_upload_segments_req_ind_msg_v01,
		.offset         = offsetof(struct
					   wlfw_m3_dump_upload_segments_req_ind_msg_v01,
					   no_of_valid_segments),
	},
	{
@@ -5102,8 +5195,8 @@ struct qmi_elem_info wlfw_m3_dump_upload_segments_req_ind_msg_v01_ei[] = {
		.elem_size      = sizeof(struct wlfw_m3_segment_info_s_v01),
		.array_type       = STATIC_ARRAY,
		.tlv_type       = 0x03,
		.offset         =
		offsetof(struct wlfw_m3_dump_upload_segments_req_ind_msg_v01,
		.offset         = offsetof(struct
					   wlfw_m3_dump_upload_segments_req_ind_msg_v01,
					   m3_segment),
		.ei_array      = wlfw_m3_segment_info_s_v01_ei,
	},
@@ -5116,4 +5209,4 @@ struct qmi_elem_info wlfw_m3_dump_upload_segments_req_ind_msg_v01_ei[] = {
EXPORT_SYMBOL(wlfw_m3_dump_upload_segments_req_ind_msg_v01_ei);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("WLAN qmi service driver");
MODULE_DESCRIPTION("WLAN FW QMI service");
+32 −20
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2021, The Linux Foundation. All rights reserved. */

#ifndef WLAN_FIRMWARE_SERVICE_V01_H
#define WLAN_FIRMWARE_SERVICE_V01_H
@@ -99,7 +99,7 @@

#define QMI_WLFW_MAX_M3_SEGMENTS_SIZE_V01 10
#define QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01 2
#define QMI_WLFW_MAX_NUM_MEM_SEG_V01 32
#define QMI_WLFW_MAX_NUM_MEM_SEG_V01 52
#define QMI_WLFW_MAX_NUM_CAL_V01 5
#define QMI_WLFW_MAX_DATA_SIZE_V01 6144
#define QMI_WLFW_FUNCTION_NAME_LEN_V01 128
@@ -396,7 +396,6 @@ struct wlfw_ind_register_req_msg_v01 {
	u8 m3_dump_upload_segments_req_enable_valid;
	u8 m3_dump_upload_segments_req_enable;
};

#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 86
extern struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[];

@@ -511,10 +510,8 @@ struct wlfw_cap_resp_msg_v01 {
	u8 rd_card_chain_cap_valid;
	enum wlfw_rd_card_chain_cap_v01 rd_card_chain_cap;
	u8 dev_mem_info_valid;
	struct wlfw_dev_mem_info_s_v01
		dev_mem_info[QMI_WLFW_MAX_DEV_MEM_NUM_V01];
	struct wlfw_dev_mem_info_s_v01 dev_mem_info[QMI_WLFW_MAX_DEV_MEM_NUM_V01];
};

#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 320
extern struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[];

@@ -552,8 +549,11 @@ struct wlfw_cal_report_req_msg_v01 {
	u8 xo_cal_data;
	u8 cal_remove_supported_valid;
	u8 cal_remove_supported;
	u8 cal_file_download_size_valid;
	u64 cal_file_download_size;
};
#define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 32

#define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 43
extern struct qmi_elem_info wlfw_cal_report_req_msg_v01_ei[];

struct wlfw_cal_report_resp_msg_v01 {
@@ -779,14 +779,16 @@ struct wlfw_request_mem_ind_msg_v01 {
	u32 mem_seg_len;
	struct wlfw_mem_seg_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
};
#define WLFW_REQUEST_MEM_IND_MSG_V01_MAX_MSG_LEN 1124

#define WLFW_REQUEST_MEM_IND_MSG_V01_MAX_MSG_LEN 1824
extern struct qmi_elem_info wlfw_request_mem_ind_msg_v01_ei[];

struct wlfw_respond_mem_req_msg_v01 {
	u32 mem_seg_len;
	struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
};
#define WLFW_RESPOND_MEM_REQ_MSG_V01_MAX_MSG_LEN 548

#define WLFW_RESPOND_MEM_REQ_MSG_V01_MAX_MSG_LEN 888
extern struct qmi_elem_info wlfw_respond_mem_req_msg_v01_ei[];

struct wlfw_respond_mem_resp_msg_v01 {
@@ -807,7 +809,6 @@ struct wlfw_fw_init_done_ind_msg_v01 {
	u8 hang_data_length_valid;
	u16 hang_data_length;
};

#define WLFW_FW_INIT_DONE_IND_MSG_V01_MAX_MSG_LEN 12
extern struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[];

@@ -873,28 +874,33 @@ struct wlfw_xo_cal_ind_msg_v01 {
extern struct qmi_elem_info wlfw_xo_cal_ind_msg_v01_ei[];

struct wlfw_cal_done_ind_msg_v01 {
	char placeholder;
	u8 cal_file_upload_size_valid;
	u64 cal_file_upload_size;
};
#define WLFW_CAL_DONE_IND_MSG_V01_MAX_MSG_LEN 0

#define WLFW_CAL_DONE_IND_MSG_V01_MAX_MSG_LEN 11
extern struct qmi_elem_info wlfw_cal_done_ind_msg_v01_ei[];

struct wlfw_qdss_trace_req_mem_ind_msg_v01 {
	u32 mem_seg_len;
	struct wlfw_mem_seg_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
};
#define WLFW_QDSS_TRACE_REQ_MEM_IND_MSG_V01_MAX_MSG_LEN 1124

#define WLFW_QDSS_TRACE_REQ_MEM_IND_MSG_V01_MAX_MSG_LEN 1824
extern struct qmi_elem_info wlfw_qdss_trace_req_mem_ind_msg_v01_ei[];

struct wlfw_qdss_trace_mem_info_req_msg_v01 {
	u32 mem_seg_len;
	struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
};
#define WLFW_QDSS_TRACE_MEM_INFO_REQ_MSG_V01_MAX_MSG_LEN 548

#define WLFW_QDSS_TRACE_MEM_INFO_REQ_MSG_V01_MAX_MSG_LEN 888
extern struct qmi_elem_info wlfw_qdss_trace_mem_info_req_msg_v01_ei[];

struct wlfw_qdss_trace_mem_info_resp_msg_v01 {
	struct qmi_response_type_v01 resp;
};

#define WLFW_QDSS_TRACE_MEM_INFO_RESP_MSG_V01_MAX_MSG_LEN 7
extern struct qmi_elem_info wlfw_qdss_trace_mem_info_resp_msg_v01_ei[];

@@ -907,7 +913,8 @@ struct wlfw_qdss_trace_save_ind_msg_v01 {
	u8 file_name_valid;
	char file_name[QMI_WLFW_MAX_STR_LEN_V01 + 1];
};
#define WLFW_QDSS_TRACE_SAVE_IND_MSG_V01_MAX_MSG_LEN 581

#define WLFW_QDSS_TRACE_SAVE_IND_MSG_V01_MAX_MSG_LEN 921
extern struct qmi_elem_info wlfw_qdss_trace_save_ind_msg_v01_ei[];

struct wlfw_qdss_trace_data_req_msg_v01 {
@@ -973,7 +980,8 @@ struct wlfw_qdss_trace_free_ind_msg_v01 {
	u32 mem_seg_len;
	struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
};
#define WLFW_QDSS_TRACE_FREE_IND_MSG_V01_MAX_MSG_LEN 548

#define WLFW_QDSS_TRACE_FREE_IND_MSG_V01_MAX_MSG_LEN 888
extern struct qmi_elem_info wlfw_qdss_trace_free_ind_msg_v01_ei[];

struct wlfw_shutdown_req_msg_v01 {
@@ -1052,6 +1060,7 @@ extern struct qmi_elem_info wlfw_get_info_req_msg_v01_ei[];
struct wlfw_get_info_resp_msg_v01 {
	struct qmi_response_type_v01 resp;
};

#define WLFW_GET_INFO_RESP_MSG_V01_MAX_MSG_LEN 7
extern struct qmi_elem_info wlfw_get_info_resp_msg_v01_ei[];

@@ -1080,8 +1089,13 @@ struct wlfw_device_info_resp_msg_v01 {
	u64 bar_addr;
	u8 bar_size_valid;
	u32 bar_size;
	u8 mhi_state_info_addr_valid;
	u64 mhi_state_info_addr;
	u8 mhi_state_info_size_valid;
	u32 mhi_state_info_size;
};
#define WLFW_DEVICE_INFO_RESP_MSG_V01_MAX_MSG_LEN 25

#define WLFW_DEVICE_INFO_RESP_MSG_V01_MAX_MSG_LEN 43
extern struct qmi_elem_info wlfw_device_info_resp_msg_v01_ei[];

struct wlfw_m3_dump_upload_req_ind_msg_v01 {
@@ -1169,10 +1183,8 @@ extern struct qmi_elem_info wlfw_pcie_gen_switch_resp_msg_v01_ei[];
struct wlfw_m3_dump_upload_segments_req_ind_msg_v01 {
	u32 pdev_id;
	u32 no_of_valid_segments;
	struct wlfw_m3_segment_info_s_v01
		m3_segment[QMI_WLFW_MAX_M3_SEGMENTS_SIZE_V01];
	struct wlfw_m3_segment_info_s_v01 m3_segment[QMI_WLFW_MAX_M3_SEGMENTS_SIZE_V01];
};

#define WLFW_M3_DUMP_UPLOAD_SEGMENTS_REQ_IND_MSG_V01_MAX_MSG_LEN 387
extern struct qmi_elem_info wlfw_m3_dump_upload_segments_req_ind_msg_v01_ei[];

+90 −54
Original line number Diff line number Diff line
@@ -668,6 +668,17 @@ static int icnss_driver_event_server_arrive(struct icnss_priv *priv,
			     &priv->mem_base_pa,
			     priv->mem_base_va);

		if (priv->mhi_state_info_pa)
			priv->mhi_state_info_va = devm_ioremap(&priv->pdev->dev,
						priv->mhi_state_info_pa,
						PAGE_SIZE);
		if (!priv->mhi_state_info_va)
			icnss_pr_err("Ioremap failed for MHI info address\n");

		icnss_pr_dbg("MHI state info Address pa: %pa, va: 0x%pK\n",
			     &priv->mhi_state_info_pa,
			     priv->mhi_state_info_va);

		icnss_wlfw_bdf_dnld_send_sync(priv, ICNSS_BDF_REGDB);

		ret = icnss_wlfw_bdf_dnld_send_sync(priv,
@@ -1497,6 +1508,7 @@ static void icnss_driver_event_work(struct work_struct *work)
			break;
		case ICNSS_DRIVER_EVENT_M3_DUMP_UPLOAD_REQ:
			ret = icnss_m3_dump_upload_req_hdlr(priv, event->data);
			break;
		case ICNSS_DRIVER_EVENT_QDSS_TRACE_REQ_DATA:
			ret = icnss_qdss_trace_req_data_hdlr(priv,
							     event->data);
@@ -2147,7 +2159,8 @@ static int icnss_enable_recovery(struct icnss_priv *priv)
	return 0;
}

static int icnss_trigger_ssr_smp2p(struct icnss_priv *priv)
static int icnss_send_smp2p(struct icnss_priv *priv,
			    enum icnss_smp2p_msg_id msg_id)
{
	unsigned int value = 0;
	int ret;
@@ -2155,19 +2168,22 @@ static int icnss_trigger_ssr_smp2p(struct icnss_priv *priv)
	if (IS_ERR(priv->smp2p_info.smem_state))
		return -EINVAL;

	if (test_bit(ICNSS_FW_DOWN, &priv->state))
		return -ENODEV;

	value |= priv->smp2p_info.seq++;
	value <<= ICNSS_SMEM_SEQ_NO_POS;
	value |= ICNSS_TRIGGER_SSR;
	value |= msg_id;

	icnss_pr_vdbg1("Sending SMP2P value: 0x%X\n", value);

	ret = qcom_smem_state_update_bits(
			priv->smp2p_info.smem_state,
			ICNSS_SMEM_VALUE_MASK,
			value);
	if (ret)
		icnss_pr_vdbg1("Error in SMP2P sent ret: %d\n", ret);
		icnss_pr_vdbg1("Error in SMP2P send ret: %d\n", ret);

	icnss_pr_vdbg1("Initiate Root PD restart. SMP2P sent value: 0x%X\n",
		     value);
	set_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
	return ret;
}

@@ -2639,6 +2655,22 @@ int icnss_get_soc_info(struct device *dev, struct icnss_soc_info *info)
}
EXPORT_SYMBOL(icnss_get_soc_info);

int icnss_get_mhi_state(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);

	if (!priv) {
		icnss_pr_err("Platform driver not initialized\n");
		return -EINVAL;
	}

	if (!priv->mhi_state_info_va)
		return -ENOMEM;

	return ioread32(priv->mhi_state_info_va);
}
EXPORT_SYMBOL(icnss_get_mhi_state);

int icnss_set_fw_log_mode(struct device *dev, uint8_t fw_log_mode)
{
	int ret;
@@ -2722,9 +2754,6 @@ int icnss_is_device_awake(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);

	if (!dev)
		return -ENODEV;

	if (!priv) {
		icnss_pr_err("Platform driver not initialized\n");
		return -EINVAL;
@@ -2734,6 +2763,22 @@ int icnss_is_device_awake(struct device *dev)
}
EXPORT_SYMBOL(icnss_is_device_awake);

int icnss_is_pci_ep_awake(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);

	if (!priv) {
		icnss_pr_err("Platform driver not initialized\n");
		return -EINVAL;
	}

	if (!priv->mhi_state_info_va)
		return -ENOMEM;

	return ioread32(priv->mhi_state_info_va + ICNSS_PCI_EP_WAKE_OFFSET);
}
EXPORT_SYMBOL(icnss_is_pci_ep_awake);

int icnss_athdiag_read(struct device *dev, uint32_t offset,
		       uint32_t mem_type, uint32_t data_len,
		       uint8_t *output)
@@ -3027,8 +3072,13 @@ int icnss_trigger_recovery(struct device *dev)
		goto out;
	}

	if (priv->device_id == WCN6750_DEVICE_ID)
		return icnss_trigger_ssr_smp2p(priv);
	if (priv->device_id == WCN6750_DEVICE_ID) {
		icnss_pr_vdbg1("Initiate Root PD restart");
		ret = icnss_send_smp2p(priv, ICNSS_TRIGGER_SSR);
		if (!ret)
			set_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
		return ret;
	}

	if (!test_bit(ICNSS_PDR_REGISTERED, &priv->state)) {
		icnss_pr_err("PD restart not enabled to trigger recovery: state: 0x%lx\n",
@@ -3104,8 +3154,6 @@ EXPORT_SYMBOL(icnss_idle_restart);
int icnss_exit_power_save(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);
	unsigned int value = 0;
	int ret;

	icnss_pr_vdbg1("Calling Exit Power Save\n");

@@ -3113,21 +3161,34 @@ int icnss_exit_power_save(struct device *dev)
	    !test_bit(ICNSS_MODE_ON, &priv->state))
		return 0;

	value |= priv->smp2p_info.seq++;
	value <<= ICNSS_SMEM_SEQ_NO_POS;
	value |= ICNSS_POWER_SAVE_EXIT;
	ret = qcom_smem_state_update_bits(
			priv->smp2p_info.smem_state,
			ICNSS_SMEM_VALUE_MASK,
			value);
	if (ret)
		icnss_pr_vdbg1("Error in SMP2P sent ret: %d\n", ret);

	icnss_pr_vdbg1("SMP2P sent value: 0x%X\n", value);
	return ret;
	return icnss_send_smp2p(priv, ICNSS_POWER_SAVE_EXIT);
}
EXPORT_SYMBOL(icnss_exit_power_save);

int icnss_prevent_l1(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);

	if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
	    !test_bit(ICNSS_MODE_ON, &priv->state))
		return 0;

	return icnss_send_smp2p(priv, ICNSS_PCI_EP_POWER_SAVE_EXIT);
}
EXPORT_SYMBOL(icnss_prevent_l1);

void icnss_allow_l1(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);

	if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
	    !test_bit(ICNSS_MODE_ON, &priv->state))
		return;

	icnss_send_smp2p(priv, ICNSS_PCI_EP_POWER_SAVE_ENTER);
}
EXPORT_SYMBOL(icnss_allow_l1);

void icnss_allow_recursive_recovery(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);
@@ -3957,7 +4018,6 @@ static int icnss_remove(struct platform_device *pdev)
static int icnss_pm_suspend(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);
	unsigned int value = 0;
	int ret = 0;

	if (priv->magic != ICNSS_MAGIC) {
@@ -3981,19 +4041,7 @@ static int icnss_pm_suspend(struct device *dev)
			    !test_bit(ICNSS_MODE_ON, &priv->state))
				return 0;

			value |= priv->smp2p_info.seq++;
			value <<= ICNSS_SMEM_SEQ_NO_POS;
			value |= ICNSS_POWER_SAVE_ENTER;

			ret = qcom_smem_state_update_bits(
				priv->smp2p_info.smem_state,
				ICNSS_SMEM_VALUE_MASK,
				value);
			if (ret)
				icnss_pr_vdbg1("Error in SMP2P sent ret: %d\n",
					     ret);

			icnss_pr_vdbg1("SMP2P sent value: 0x%X\n", value);
			ret = icnss_send_smp2p(priv, ICNSS_POWER_SAVE_ENTER);
		}
		priv->stats.pm_suspend++;
		set_bit(ICNSS_PM_SUSPEND, &priv->state);
@@ -4094,7 +4142,6 @@ static int icnss_pm_resume_noirq(struct device *dev)
static int icnss_pm_runtime_suspend(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);
	unsigned int value = 0;
	int ret = 0;

	if (priv->device_id != WCN6750_DEVICE_ID) {
@@ -4119,18 +4166,7 @@ static int icnss_pm_runtime_suspend(struct device *dev)
		    !test_bit(ICNSS_MODE_ON, &priv->state))
			return 0;

		value |= priv->smp2p_info.seq++;
		value <<= ICNSS_SMEM_SEQ_NO_POS;
		value |= ICNSS_POWER_SAVE_ENTER;

		ret = qcom_smem_state_update_bits(
				priv->smp2p_info.smem_state,
				ICNSS_SMEM_VALUE_MASK,
				value);
		if (ret)
			icnss_pr_vdbg1("Error in SMP2P sent ret: %d\n", ret);

		icnss_pr_vdbg1("SMP2P sent value: 0x%X\n", value);
		ret = icnss_send_smp2p(priv, ICNSS_POWER_SAVE_ENTER);
	}
out:
	return ret;
+6 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#define ICNSS_SMEM_SEQ_NO_POS 16
#define QCA6750_PATH_PREFIX    "qca6750/"
#define ICNSS_MAX_FILE_NAME      35
#define ICNSS_PCI_EP_WAKE_OFFSET 4

extern uint64_t dynamic_feature_mask;

@@ -182,6 +183,8 @@ enum icnss_smp2p_msg_id {
	ICNSS_POWER_SAVE_ENTER = 1,
	ICNSS_POWER_SAVE_EXIT,
	ICNSS_TRIGGER_SSR,
	ICNSS_PCI_EP_POWER_SAVE_ENTER = 6,
	ICNSS_PCI_EP_POWER_SAVE_EXIT,
};

struct icnss_stats {
@@ -353,6 +356,9 @@ struct icnss_priv {
	phys_addr_t mem_base_pa;
	void __iomem *mem_base_va;
	u32 mem_base_size;
	phys_addr_t mhi_state_info_pa;
	void __iomem *mhi_state_info_va;
	u32 mhi_state_info_size;
	struct iommu_domain *iommu_domain;
	dma_addr_t smmu_iova_start;
	size_t smmu_iova_len;
+9 −0
Original line number Diff line number Diff line
@@ -335,6 +335,15 @@ int wlfw_device_info_send_msg(struct icnss_priv *priv)
		goto out;
	}

	if (resp->mhi_state_info_addr_valid)
		priv->mhi_state_info_pa = resp->mhi_state_info_addr;

	if (resp->mhi_state_info_size_valid)
		priv->mhi_state_info_size = resp->mhi_state_info_size;

	if (!priv->mhi_state_info_pa)
		icnss_pr_err("Fail to get MHI info address\n");

	kfree(resp);
	kfree(req);
	return 0;
Loading