Forráskód Böngészése

cnss2: Feature update for OL CPR

Open Loop CPR feature is extended to support multiple VRegs. Add IDL
data structures, device tree setup for WLAN device PMU pin to platform
VReg mapping and handling for new OL CPR params from FW.

Change-Id: Ibdcc5b30521c01e12124b32bd6291def98bd9516
Manikandan Mohan 2 éve
szülő
commit
eadcd47888
5 módosított fájl, 596 hozzáadás és 8 törlés
  1. 4 2
      cnss2/main.h
  2. 152 1
      cnss2/power.c
  3. 3 0
      cnss2/qmi.c
  4. 337 1
      cnss_utils/wlan_firmware_service_v01.c
  5. 100 4
      cnss_utils/wlan_firmware_service_v01.h

+ 4 - 2
cnss2/main.h

@@ -538,8 +538,8 @@ struct cnss_plat_data {
 	struct mbox_client mbox_client_data;
 	struct mbox_chan *mbox_chan;
 	const char *vreg_ol_cpr, *vreg_ipa;
-	const char **pdc_init_table, **vreg_pdc_map;
-	int pdc_init_table_len, vreg_pdc_map_len;
+	const char **pdc_init_table, **vreg_pdc_map, **pmu_vreg_map;
+	int pdc_init_table_len, vreg_pdc_map_len, pmu_vreg_map_len;
 	bool adsp_pc_enabled;
 	u64 feature_list;
 	u32 is_converged_dt;
@@ -622,6 +622,8 @@ int cnss_aop_mbox_init(struct cnss_plat_data *plat_priv);
 int cnss_aop_pdc_reconfig(struct cnss_plat_data *plat_priv);
 int cnss_aop_send_msg(struct cnss_plat_data *plat_priv, char *msg);
 void cnss_power_misc_params_init(struct cnss_plat_data *plat_priv);
+int cnss_aop_ol_cpr_cfg_setup(struct cnss_plat_data *plat_priv,
+			      struct wlfw_pmu_cfg_v01 *fw_pmu_cfg);
 int cnss_request_firmware_direct(struct cnss_plat_data *plat_priv,
 				 const struct firmware **fw_entry,
 				 const char *filename);

+ 152 - 1
cnss2/power.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/clk.h>
@@ -81,6 +81,11 @@ static struct cnss_clk_cfg cnss_clk_list[] = {
 #define BT_CXMX_VOLTAGE_MV		950
 #define CNSS_MBOX_MSG_MAX_LEN 64
 #define CNSS_MBOX_TIMEOUT_MS 1000
+/* Platform HW config */
+#define CNSS_PMIC_VOLTAGE_STEP 4
+#define CNSS_PMIC_AUTO_HEADROOM 16
+#define CNSS_IR_DROP_WAKE 30
+#define CNSS_IR_DROP_SLEEP 10
 
 /**
  * enum cnss_aop_vreg_param: Voltage regulator TCS param
@@ -1302,6 +1307,127 @@ static int cnss_aop_set_vreg_param(struct cnss_plat_data *plat_priv,
 
 	return cnss_aop_send_msg(plat_priv, msg);
 }
+
+int cnss_aop_ol_cpr_cfg_setup(struct cnss_plat_data *plat_priv,
+			      struct wlfw_pmu_cfg_v01 *fw_pmu_cfg)
+{
+	const char *pmu_pin, *vreg;
+	struct wlfw_pmu_param_v01 *fw_pmu_param;
+	u32 fw_pmu_param_len, i, j, plat_vreg_param_len = 0;
+	int ret = 0;
+	struct platform_vreg_param {
+		char vreg[MAX_PROP_SIZE];
+		u32 wake_volt;
+		u32 sleep_volt;
+	} plat_vreg_param[QMI_WLFW_PMU_PARAMS_MAX_V01] = {0};
+	static bool config_done;
+
+	if (config_done)
+		return 0;
+
+	if (plat_priv->pmu_vreg_map_len <= 0 || !plat_priv->mbox_chan ||
+	    !plat_priv->pmu_vreg_map) {
+		cnss_pr_dbg("Mbox channel / PMU VReg Map not configured\n");
+		goto end;
+	}
+	if (!fw_pmu_cfg)
+		return -EINVAL;
+
+	fw_pmu_param = fw_pmu_cfg->pmu_param;
+	fw_pmu_param_len = fw_pmu_cfg->pmu_param_len;
+	/* Get PMU Pin name to Platfom Vreg Mapping */
+	for (i = 0; i < fw_pmu_param_len; i++) {
+		cnss_pr_dbg("FW_PMU Data: %s %d %d %d %d\n",
+			    fw_pmu_param[i].pin_name,
+			    fw_pmu_param[i].wake_volt_valid,
+			    fw_pmu_param[i].wake_volt,
+			    fw_pmu_param[i].sleep_volt_valid,
+			    fw_pmu_param[i].sleep_volt);
+
+		if (!fw_pmu_param[i].wake_volt_valid &&
+		    !fw_pmu_param[i].sleep_volt_valid)
+			continue;
+
+		vreg = NULL;
+		for (j = 0; j < plat_priv->pmu_vreg_map_len; j += 2) {
+			pmu_pin = plat_priv->pmu_vreg_map[j];
+			if (strnstr(pmu_pin, fw_pmu_param[i].pin_name,
+				    strlen(pmu_pin))) {
+				vreg = plat_priv->pmu_vreg_map[j + 1];
+				break;
+			}
+		}
+		if (!vreg) {
+			cnss_pr_err("No VREG mapping for %s\n",
+				    fw_pmu_param[i].pin_name);
+			continue;
+		} else {
+			cnss_pr_dbg("%s mapped to %s\n",
+				    fw_pmu_param[i].pin_name, vreg);
+		}
+		for (j = 0; j < QMI_WLFW_PMU_PARAMS_MAX_V01; j++) {
+			u32 wake_volt = 0, sleep_volt = 0;
+
+			if (plat_vreg_param[j].vreg[0] == '\0')
+				strlcpy(plat_vreg_param[j].vreg, vreg,
+					sizeof(plat_vreg_param[j].vreg));
+			else if (!strnstr(plat_vreg_param[j].vreg, vreg,
+					  strlen(plat_vreg_param[j].vreg)))
+				continue;
+
+			if (fw_pmu_param[i].wake_volt_valid)
+				wake_volt = roundup(fw_pmu_param[i].wake_volt,
+						    CNSS_PMIC_VOLTAGE_STEP) -
+						    CNSS_PMIC_AUTO_HEADROOM +
+						    CNSS_IR_DROP_WAKE;
+			if (fw_pmu_param[i].sleep_volt_valid)
+				sleep_volt = roundup(fw_pmu_param[i].sleep_volt,
+						     CNSS_PMIC_VOLTAGE_STEP) -
+						     CNSS_PMIC_AUTO_HEADROOM +
+						     CNSS_IR_DROP_SLEEP;
+
+			plat_vreg_param[j].wake_volt =
+				(wake_volt > plat_vreg_param[j].wake_volt ?
+				 wake_volt : plat_vreg_param[j].wake_volt);
+			plat_vreg_param[j].sleep_volt =
+				(sleep_volt > plat_vreg_param[j].sleep_volt ?
+				 sleep_volt : plat_vreg_param[j].sleep_volt);
+
+			plat_vreg_param_len = (plat_vreg_param_len > j ?
+					       plat_vreg_param_len : j);
+			cnss_pr_dbg("Plat VReg Data: %s %d %d\n",
+				    plat_vreg_param[j].vreg,
+				    plat_vreg_param[j].wake_volt,
+				    plat_vreg_param[j].sleep_volt);
+			break;
+		}
+	}
+
+	for (i = 0; i <= plat_vreg_param_len; i++) {
+		if (plat_vreg_param[i].wake_volt > 0) {
+			ret =
+			cnss_aop_set_vreg_param(plat_priv,
+						plat_vreg_param[i].vreg,
+						CNSS_VREG_VOLTAGE,
+						CNSS_TCS_UP_SEQ,
+						plat_vreg_param[i].wake_volt);
+		}
+		if (plat_vreg_param[i].sleep_volt > 0) {
+			ret =
+			cnss_aop_set_vreg_param(plat_priv,
+						plat_vreg_param[i].vreg,
+						CNSS_VREG_VOLTAGE,
+						CNSS_TCS_DOWN_SEQ,
+						plat_vreg_param[i].sleep_volt);
+		}
+		if (ret < 0)
+			break;
+	}
+end:
+	config_done = true;
+	return ret;
+}
+
 #else
 int cnss_aop_mbox_init(struct cnss_plat_data *plat_priv)
 {
@@ -1326,6 +1452,12 @@ static int cnss_aop_set_vreg_param(struct cnss_plat_data *plat_priv,
 {
 	return 0;
 }
+
+int cnss_aop_ol_cpr_cfg_setup(struct cnss_plat_data *plat_priv,
+			      struct wlfw_pmu_cfg_v01 *fw_pmu_cfg)
+{
+	return 0;
+}
 #endif
 
 void cnss_power_misc_params_init(struct cnss_plat_data *plat_priv)
@@ -1370,6 +1502,22 @@ void cnss_power_misc_params_init(struct cnss_plat_data *plat_priv)
 		cnss_pr_dbg("VReg PDC Mapping not configured\n");
 	}
 
+	plat_priv->pmu_vreg_map_len =
+			of_property_count_strings(dev->of_node,
+						  "qcom,pmu_vreg_map");
+	if (plat_priv->pmu_vreg_map_len > 0) {
+		plat_priv->pmu_vreg_map = kcalloc(plat_priv->pmu_vreg_map_len,
+						  sizeof(char *), GFP_KERNEL);
+		ret =
+		of_property_read_string_array(dev->of_node, "qcom,pmu_vreg_map",
+					      plat_priv->pmu_vreg_map,
+					      plat_priv->pmu_vreg_map_len);
+		if (ret < 0)
+			cnss_pr_err("Fail to get PMU VReg Mapping\n");
+	} else {
+		cnss_pr_dbg("PMU VReg Mapping not configured\n");
+	}
+
 	/* Device DT Specific */
 	if (plat_priv->device_id == QCA6390_DEVICE_ID ||
 	    plat_priv->device_id == QCA6490_DEVICE_ID) {
@@ -1400,6 +1548,9 @@ int cnss_update_cpr_info(struct cnss_plat_data *plat_priv)
 		return -EINVAL;
 	}
 
+	if (plat_priv->device_id != QCA6490_DEVICE_ID)
+		return -EINVAL;
+
 	if (!plat_priv->vreg_ol_cpr || !plat_priv->mbox_chan) {
 		cnss_pr_dbg("Mbox channel / OL CPR Vreg not configured\n");
 	} else {

+ 3 - 0
cnss2/qmi.c

@@ -528,6 +528,9 @@ int cnss_wlfw_tgt_cap_send_sync(struct cnss_plat_data *plat_priv)
 	else
 		plat_priv->hang_data_addr_offset = 0;
 
+	if (resp->ol_cpr_cfg_valid)
+		cnss_aop_ol_cpr_cfg_setup(plat_priv, &resp->ol_cpr_cfg);
+
 	cnss_pr_dbg("Target capability: chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, otp_version: 0x%x\n",
 		    plat_priv->chip_info.chip_id,
 		    plat_priv->chip_info.chip_family,

+ 337 - 1
cnss_utils/wlan_firmware_service_v01.c

@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */
+/* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */
 
 #include "wlan_firmware_service_v01.h"
 #include <linux/module.h>
@@ -620,6 +621,111 @@ static struct qmi_elem_info wlfw_host_mlo_chip_info_s_v01_ei[] = {
 	},
 };
 
+static struct qmi_elem_info wlfw_pmu_param_v01_ei[] = {
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = 32,
+		.elem_size      = sizeof(u8),
+		.array_type       = STATIC_ARRAY,
+		.tlv_type       = 0,
+		.offset         = offsetof(struct
+					   wlfw_pmu_param_v01,
+					   pin_name),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_4_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u32),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0,
+		.offset         = offsetof(struct
+					   wlfw_pmu_param_v01,
+					   wake_volt_valid),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_4_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u32),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0,
+		.offset         = offsetof(struct
+					   wlfw_pmu_param_v01,
+					   wake_volt),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_4_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u32),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0,
+		.offset         = offsetof(struct
+					   wlfw_pmu_param_v01,
+					   sleep_volt_valid),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_4_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u32),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0,
+		.offset         = offsetof(struct
+					   wlfw_pmu_param_v01,
+					   sleep_volt),
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.array_type       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+static struct qmi_elem_info wlfw_pmu_cfg_v01_ei[] = {
+	{
+		.data_type      = QMI_DATA_LEN,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0,
+		.offset         = offsetof(struct
+					   wlfw_pmu_cfg_v01,
+					   pmu_param_len),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = QMI_WLFW_PMU_PARAMS_MAX_V01,
+		.elem_size      = sizeof(struct wlfw_pmu_param_v01),
+		.array_type       = VAR_LEN_ARRAY,
+		.tlv_type       = 0,
+		.offset         = offsetof(struct
+					   wlfw_pmu_cfg_v01,
+					   pmu_param),
+		.ei_array      = wlfw_pmu_param_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.array_type       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+static struct qmi_elem_info wlfw_shadow_reg_v3_cfg_s_v01_ei[] = {
+	{
+		.data_type      = QMI_UNSIGNED_4_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u32),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0,
+		.offset         = offsetof(struct
+					   wlfw_shadow_reg_v3_cfg_s_v01,
+					   addr),
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.array_type       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
 struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[] = {
 	{
 		.data_type      = QMI_OPT_FLAG,
@@ -1227,6 +1333,26 @@ struct qmi_elem_info wlfw_wlan_mode_req_msg_v01_ei[] = {
 					   wlfw_wlan_mode_req_msg_v01,
 					   hw_debug),
 	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x11,
+		.offset         = offsetof(struct
+					   wlfw_wlan_mode_req_msg_v01,
+					   xo_cal_data_valid),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x11,
+		.offset         = offsetof(struct
+					   wlfw_wlan_mode_req_msg_v01,
+					   xo_cal_data),
+	},
 	{
 		.data_type      = QMI_EOTI,
 		.array_type       = NO_ARRAY,
@@ -1452,6 +1578,37 @@ struct qmi_elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = {
 					   msi_cfg),
 		.ei_array      = wlfw_msi_cfg_s_v01_ei,
 	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x17,
+		.offset         = offsetof(struct
+					   wlfw_wlan_cfg_req_msg_v01,
+					   shadow_reg_v3_valid),
+	},
+	{
+		.data_type      = QMI_DATA_LEN,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x17,
+		.offset         = offsetof(struct
+					   wlfw_wlan_cfg_req_msg_v01,
+					   shadow_reg_v3_len),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = QMI_WLFW_MAX_NUM_SHADOW_REG_V3_V01,
+		.elem_size      = sizeof(struct wlfw_shadow_reg_v3_cfg_s_v01),
+		.array_type       = VAR_LEN_ARRAY,
+		.tlv_type       = 0x17,
+		.offset         = offsetof(struct
+					   wlfw_wlan_cfg_req_msg_v01,
+					   shadow_reg_v3),
+		.ei_array      = wlfw_shadow_reg_v3_cfg_s_v01_ei,
+	},
 	{
 		.data_type      = QMI_EOTI,
 		.array_type       = NO_ARRAY,
@@ -1866,6 +2023,27 @@ struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[] = {
 					   wlfw_cap_resp_msg_v01,
 					   hwid_bitmap),
 	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x22,
+		.offset         = offsetof(struct
+					   wlfw_cap_resp_msg_v01,
+					   ol_cpr_cfg_valid),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct wlfw_pmu_cfg_v01),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x22,
+		.offset         = offsetof(struct
+					   wlfw_cap_resp_msg_v01,
+					   ol_cpr_cfg),
+		.ei_array      = wlfw_pmu_cfg_v01_ei,
+	},
 	{
 		.data_type      = QMI_EOTI,
 		.array_type       = NO_ARRAY,
@@ -3645,6 +3823,26 @@ struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[] = {
 					   wlfw_host_cap_req_msg_v01,
 					   gpio_info),
 	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x2E,
+		.offset         = offsetof(struct
+					   wlfw_host_cap_req_msg_v01,
+					   fw_ini_cfg_support_valid),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x2E,
+		.offset         = offsetof(struct
+					   wlfw_host_cap_req_msg_v01,
+					   fw_ini_cfg_support),
+	},
 	{
 		.data_type      = QMI_EOTI,
 		.array_type       = NO_ARRAY,
@@ -5677,6 +5875,145 @@ struct qmi_elem_info wlfw_subsys_restart_level_resp_msg_v01_ei[] = {
 };
 EXPORT_SYMBOL(wlfw_subsys_restart_level_resp_msg_v01_ei);
 
+struct qmi_elem_info wlfw_ini_file_download_req_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_ini_file_download_req_msg_v01,
+					   file_type_valid),
+	},
+	{
+		.data_type      = QMI_SIGNED_4_BYTE_ENUM,
+		.elem_len       = 1,
+		.elem_size      = sizeof(enum wlfw_ini_file_type_v01),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x10,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   file_type),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x11,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   total_size_valid),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_4_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u32),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x11,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   total_size),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x12,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   seg_id_valid),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_4_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u32),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x12,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   seg_id),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x13,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   data_valid),
+	},
+	{
+		.data_type      = QMI_DATA_LEN,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u16),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x13,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   data_len),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = QMI_WLFW_MAX_DATA_SIZE_V01,
+		.elem_size      = sizeof(u8),
+		.array_type       = VAR_LEN_ARRAY,
+		.tlv_type       = 0x13,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   data),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x14,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   end_valid),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = 1,
+		.elem_size      = sizeof(u8),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x14,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_req_msg_v01,
+					   end),
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.array_type       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+EXPORT_SYMBOL(wlfw_ini_file_download_req_msg_v01_ei);
+
+struct qmi_elem_info wlfw_ini_file_download_resp_msg_v01_ei[] = {
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct qmi_response_type_v01),
+		.array_type       = NO_ARRAY,
+		.tlv_type       = 0x02,
+		.offset         = offsetof(struct
+					   wlfw_ini_file_download_resp_msg_v01,
+					   resp),
+		.ei_array      = qmi_response_type_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.array_type       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+EXPORT_SYMBOL(wlfw_ini_file_download_resp_msg_v01_ei);
+
 /**
  * wlfw_is_valid_dt_node_found - Check if valid device tree node present
  *
@@ -5707,7 +6044,6 @@ static int __init wlfw_init(void)
 
 	return 0;
 }
-
 module_init(wlfw_init);
 
 MODULE_LICENSE("GPL v2");

+ 100 - 4
cnss_utils/wlan_firmware_service_v01.h

@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */
+/* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */
 
 #ifndef WLAN_FIRMWARE_SERVICE_V01_H
 #define WLAN_FIRMWARE_SERVICE_V01_H
@@ -13,6 +14,7 @@
 #define QMI_WLFW_SUBSYS_RESTART_LEVEL_REQ_V01 0x0055
 #define QMI_WLFW_POWER_SAVE_RESP_V01 0x0050
 #define QMI_WLFW_CAP_REQ_V01 0x0024
+#define QMI_WLFW_INI_FILE_DOWNLOAD_RESP_V01 0x0056
 #define QMI_WLFW_CAL_REPORT_REQ_V01 0x0026
 #define QMI_WLFW_M3_INFO_RESP_V01 0x003C
 #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026
@@ -96,6 +98,7 @@
 #define QMI_WLFW_WFC_CALL_STATUS_REQ_V01 0x0049
 #define QMI_WLFW_DEVICE_INFO_RESP_V01 0x004C
 #define QMI_WLFW_MSA_READY_RESP_V01 0x002E
+#define QMI_WLFW_INI_FILE_DOWNLOAD_REQ_V01 0x0056
 #define QMI_WLFW_QDSS_TRACE_FREE_IND_V01 0x0046
 #define QMI_WLFW_QDSS_MEM_READY_IND_V01 0x0052
 
@@ -111,6 +114,7 @@
 #define QMI_WLFW_MAC_ADDR_SIZE_V01 6
 #define QMI_WLFW_MAX_NUM_GPIO_INFO_V01 20
 #define QMI_WLFW_MAX_NUM_MEM_CFG_V01 2
+#define QMI_WLFW_PMU_PARAMS_MAX_V01 16
 #define QMI_WLFW_MAX_NUM_MEM_SEG_V01 52
 #define QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01 256
 #define QMI_WLFW_MAX_DATA_SIZE_V01 6144
@@ -119,7 +123,9 @@
 #define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32
 #define QMI_WLFW_MAX_M3_SEGMENTS_SIZE_V01 10
 #define QMI_WLFW_MAX_STR_LEN_V01 16
+#define QMI_WLFW_MAX_NUM_SHADOW_REG_V3_V01 60
 #define QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01 36
+#define QMI_WLFW_MAX_NUM_SHADOW_REG_V3_USAGE_V01 40
 #define QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01 6144
 #define QMI_WLFW_MAX_NUM_GPIO_V01 32
 #define QMI_WLFW_MAX_NUM_MLO_CHIPS_V01 3
@@ -274,6 +280,12 @@ enum wlfw_gpio_info_type_v01 {
 	WLFW_GPIO_INFO_TYPE_MAX_VAL_V01 = INT_MAX,
 };
 
+enum wlfw_ini_file_type_v01 {
+	WLFW_INI_FILE_TYPE_MIN_VAL_V01 = INT_MIN,
+	WLFW_INI_CFG_FILE_V01 = 0,
+	WLFW_INI_FILE_TYPE_MAX_VAL_V01 = INT_MAX,
+};
+
 #define QMI_WLFW_CE_ATTR_FLAGS_V01 ((u32)0x00)
 #define QMI_WLFW_CE_ATTR_NO_SNOOP_V01 ((u32)0x01)
 #define QMI_WLFW_CE_ATTR_BYTE_SWAP_DATA_V01 ((u32)0x02)
@@ -395,6 +407,23 @@ struct wlfw_host_mlo_chip_info_s_v01 {
 	u8 valid_mlo_link_id[QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01];
 };
 
+struct wlfw_pmu_param_v01 {
+	u8 pin_name[32];
+	u32 wake_volt_valid;
+	u32 wake_volt;
+	u32 sleep_volt_valid;
+	u32 sleep_volt;
+};
+
+struct wlfw_pmu_cfg_v01 {
+	u32 pmu_param_len;
+	struct wlfw_pmu_param_v01 pmu_param[QMI_WLFW_PMU_PARAMS_MAX_V01];
+};
+
+struct wlfw_shadow_reg_v3_cfg_s_v01 {
+	u32 addr;
+};
+
 struct wlfw_ind_register_req_msg_v01 {
 	u8 fw_ready_enable_valid;
 	u8 fw_ready_enable;
@@ -437,6 +466,7 @@ 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[];
 
@@ -445,12 +475,14 @@ struct wlfw_ind_register_resp_msg_v01 {
 	u8 fw_status_valid;
 	u64 fw_status;
 };
+
 #define WLFW_IND_REGISTER_RESP_MSG_V01_MAX_MSG_LEN 18
 extern struct qmi_elem_info wlfw_ind_register_resp_msg_v01_ei[];
 
 struct wlfw_fw_ready_ind_msg_v01 {
 	char placeholder;
 };
+
 #define WLFW_FW_READY_IND_MSG_V01_MAX_MSG_LEN 0
 extern struct qmi_elem_info wlfw_fw_ready_ind_msg_v01_ei[];
 
@@ -460,6 +492,7 @@ struct wlfw_msa_ready_ind_msg_v01 {
 	u8 hang_data_length_valid;
 	u16 hang_data_length;
 };
+
 #define WLFW_MSA_READY_IND_MSG_V01_MAX_MSG_LEN 12
 extern struct qmi_elem_info wlfw_msa_ready_ind_msg_v01_ei[];
 
@@ -471,6 +504,7 @@ struct wlfw_pin_connect_result_ind_msg_v01 {
 	u8 rf_pin_result_valid;
 	u32 rf_pin_result;
 };
+
 #define WLFW_PIN_CONNECT_RESULT_IND_MSG_V01_MAX_MSG_LEN 21
 extern struct qmi_elem_info wlfw_pin_connect_result_ind_msg_v01_ei[];
 
@@ -478,13 +512,17 @@ struct wlfw_wlan_mode_req_msg_v01 {
 	enum wlfw_driver_mode_enum_v01 mode;
 	u8 hw_debug_valid;
 	u8 hw_debug;
+	u8 xo_cal_data_valid;
+	u8 xo_cal_data;
 };
-#define WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN 11
+
+#define WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN 15
 extern struct qmi_elem_info wlfw_wlan_mode_req_msg_v01_ei[];
 
 struct wlfw_wlan_mode_resp_msg_v01 {
 	struct qmi_response_type_v01 resp;
 };
+
 #define WLFW_WLAN_MODE_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_wlan_mode_resp_msg_v01_ei[];
 
@@ -508,19 +546,25 @@ struct wlfw_wlan_cfg_req_msg_v01 {
 	u8 msi_cfg_valid;
 	u32 msi_cfg_len;
 	struct wlfw_msi_cfg_s_v01 msi_cfg[QMI_WLFW_MAX_NUM_CE_V01];
+	u8 shadow_reg_v3_valid;
+	u32 shadow_reg_v3_len;
+	struct wlfw_shadow_reg_v3_cfg_s_v01 shadow_reg_v3[QMI_WLFW_MAX_NUM_SHADOW_REG_V3_V01];
 };
-#define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 866
+
+#define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 1110
 extern struct qmi_elem_info wlfw_wlan_cfg_req_msg_v01_ei[];
 
 struct wlfw_wlan_cfg_resp_msg_v01 {
 	struct qmi_response_type_v01 resp;
 };
+
 #define WLFW_WLAN_CFG_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_wlan_cfg_resp_msg_v01_ei[];
 
 struct wlfw_cap_req_msg_v01 {
 	char placeholder;
 };
+
 #define WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN 0
 extern struct qmi_elem_info wlfw_cap_req_msg_v01_ei[];
 
@@ -562,9 +606,11 @@ struct wlfw_cap_resp_msg_v01 {
 	enum wlfw_bdf_dnld_method_v01 bdf_dnld_method;
 	u8 hwid_bitmap_valid;
 	u8 hwid_bitmap;
+	u8 ol_cpr_cfg_valid;
+	struct wlfw_pmu_cfg_v01 ol_cpr_cfg;
 };
 
-#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 362
+#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 1134
 extern struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[];
 
 struct wlfw_bdf_download_req_msg_v01 {
@@ -583,6 +629,7 @@ struct wlfw_bdf_download_req_msg_v01 {
 	u8 bdf_type_valid;
 	u8 bdf_type;
 };
+
 #define WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6182
 extern struct qmi_elem_info wlfw_bdf_download_req_msg_v01_ei[];
 
@@ -591,6 +638,7 @@ struct wlfw_bdf_download_resp_msg_v01 {
 	u8 host_bdf_data_valid;
 	u64 host_bdf_data;
 };
+
 #define WLFW_BDF_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 18
 extern struct qmi_elem_info wlfw_bdf_download_resp_msg_v01_ei[];
 
@@ -604,12 +652,14 @@ struct wlfw_cal_report_req_msg_v01 {
 	u8 cal_file_download_size_valid;
 	u64 cal_file_download_size;
 };
+
 #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 {
 	struct qmi_response_type_v01 resp;
 };
+
 #define WLFW_CAL_REPORT_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_cal_report_resp_msg_v01_ei[];
 
@@ -620,6 +670,7 @@ struct wlfw_initiate_cal_download_ind_msg_v01 {
 	u8 cal_data_location_valid;
 	u32 cal_data_location;
 };
+
 #define WLFW_INITIATE_CAL_DOWNLOAD_IND_MSG_V01_MAX_MSG_LEN 21
 extern struct qmi_elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[];
 
@@ -639,12 +690,14 @@ struct wlfw_cal_download_req_msg_v01 {
 	u8 cal_data_location_valid;
 	u32 cal_data_location;
 };
+
 #define WLFW_CAL_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6185
 extern struct qmi_elem_info wlfw_cal_download_req_msg_v01_ei[];
 
 struct wlfw_cal_download_resp_msg_v01 {
 	struct qmi_response_type_v01 resp;
 };
+
 #define WLFW_CAL_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_cal_download_resp_msg_v01_ei[];
 
@@ -654,6 +707,7 @@ struct wlfw_initiate_cal_update_ind_msg_v01 {
 	u8 cal_data_location_valid;
 	u32 cal_data_location;
 };
+
 #define WLFW_INITIATE_CAL_UPDATE_IND_MSG_V01_MAX_MSG_LEN 21
 extern struct qmi_elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[];
 
@@ -661,6 +715,7 @@ struct wlfw_cal_update_req_msg_v01 {
 	enum wlfw_cal_temp_id_enum_v01 cal_id;
 	u32 seg_id;
 };
+
 #define WLFW_CAL_UPDATE_REQ_MSG_V01_MAX_MSG_LEN 14
 extern struct qmi_elem_info wlfw_cal_update_req_msg_v01_ei[];
 
@@ -680,6 +735,7 @@ struct wlfw_cal_update_resp_msg_v01 {
 	u8 cal_data_location_valid;
 	u32 cal_data_location;
 };
+
 #define WLFW_CAL_UPDATE_RESP_MSG_V01_MAX_MSG_LEN 6188
 extern struct qmi_elem_info wlfw_cal_update_resp_msg_v01_ei[];
 
@@ -687,6 +743,7 @@ struct wlfw_msa_info_req_msg_v01 {
 	u64 msa_addr;
 	u32 size;
 };
+
 #define WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN 18
 extern struct qmi_elem_info wlfw_msa_info_req_msg_v01_ei[];
 
@@ -695,18 +752,21 @@ struct wlfw_msa_info_resp_msg_v01 {
 	u32 mem_region_info_len;
 	struct wlfw_memory_region_info_s_v01 mem_region_info[QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01];
 };
+
 #define WLFW_MSA_INFO_RESP_MSG_V01_MAX_MSG_LEN 37
 extern struct qmi_elem_info wlfw_msa_info_resp_msg_v01_ei[];
 
 struct wlfw_msa_ready_req_msg_v01 {
 	char placeholder;
 };
+
 #define WLFW_MSA_READY_REQ_MSG_V01_MAX_MSG_LEN 0
 extern struct qmi_elem_info wlfw_msa_ready_req_msg_v01_ei[];
 
 struct wlfw_msa_ready_resp_msg_v01 {
 	struct qmi_response_type_v01 resp;
 };
+
 #define WLFW_MSA_READY_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_msa_ready_resp_msg_v01_ei[];
 
@@ -714,12 +774,14 @@ struct wlfw_ini_req_msg_v01 {
 	u8 enablefwlog_valid;
 	u8 enablefwlog;
 };
+
 #define WLFW_INI_REQ_MSG_V01_MAX_MSG_LEN 4
 extern struct qmi_elem_info wlfw_ini_req_msg_v01_ei[];
 
 struct wlfw_ini_resp_msg_v01 {
 	struct qmi_response_type_v01 resp;
 };
+
 #define WLFW_INI_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_ini_resp_msg_v01_ei[];
 
@@ -728,6 +790,7 @@ struct wlfw_athdiag_read_req_msg_v01 {
 	u32 mem_type;
 	u32 data_len;
 };
+
 #define WLFW_ATHDIAG_READ_REQ_MSG_V01_MAX_MSG_LEN 21
 extern struct qmi_elem_info wlfw_athdiag_read_req_msg_v01_ei[];
 
@@ -737,6 +800,7 @@ struct wlfw_athdiag_read_resp_msg_v01 {
 	u32 data_len;
 	u8 data[QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01];
 };
+
 #define WLFW_ATHDIAG_READ_RESP_MSG_V01_MAX_MSG_LEN 6156
 extern struct qmi_elem_info wlfw_athdiag_read_resp_msg_v01_ei[];
 
@@ -746,24 +810,28 @@ struct wlfw_athdiag_write_req_msg_v01 {
 	u32 data_len;
 	u8 data[QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01];
 };
+
 #define WLFW_ATHDIAG_WRITE_REQ_MSG_V01_MAX_MSG_LEN 6163
 extern struct qmi_elem_info wlfw_athdiag_write_req_msg_v01_ei[];
 
 struct wlfw_athdiag_write_resp_msg_v01 {
 	struct qmi_response_type_v01 resp;
 };
+
 #define WLFW_ATHDIAG_WRITE_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_athdiag_write_resp_msg_v01_ei[];
 
 struct wlfw_vbatt_req_msg_v01 {
 	u64 voltage_uv;
 };
+
 #define WLFW_VBATT_REQ_MSG_V01_MAX_MSG_LEN 11
 extern struct qmi_elem_info wlfw_vbatt_req_msg_v01_ei[];
 
 struct wlfw_vbatt_resp_msg_v01 {
 	struct qmi_response_type_v01 resp;
 };
+
 #define WLFW_VBATT_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_vbatt_resp_msg_v01_ei[];
 
@@ -771,12 +839,14 @@ struct wlfw_mac_addr_req_msg_v01 {
 	u8 mac_addr_valid;
 	u8 mac_addr[QMI_WLFW_MAC_ADDR_SIZE_V01];
 };
+
 #define WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN 9
 extern struct qmi_elem_info wlfw_mac_addr_req_msg_v01_ei[];
 
 struct wlfw_mac_addr_resp_msg_v01 {
 	struct qmi_response_type_v01 resp;
 };
+
 #define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_mac_addr_resp_msg_v01_ei[];
 
@@ -843,9 +913,11 @@ struct wlfw_host_cap_req_msg_v01 {
 	u8 gpio_info_valid;
 	u32 gpio_info_len;
 	u32 gpio_info[QMI_WLFW_MAX_NUM_GPIO_INFO_V01];
+	u8 fw_ini_cfg_support_valid;
+	u8 fw_ini_cfg_support;
 };
 
-#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 487
+#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 491
 extern struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[];
 
 struct wlfw_host_cap_resp_msg_v01 {
@@ -1323,4 +1395,28 @@ struct wlfw_subsys_restart_level_resp_msg_v01 {
 #define WLFW_SUBSYS_RESTART_LEVEL_RESP_MSG_V01_MAX_MSG_LEN 7
 extern struct qmi_elem_info wlfw_subsys_restart_level_resp_msg_v01_ei[];
 
+struct wlfw_ini_file_download_req_msg_v01 {
+	u8 file_type_valid;
+	enum wlfw_ini_file_type_v01 file_type;
+	u8 total_size_valid;
+	u32 total_size;
+	u8 seg_id_valid;
+	u32 seg_id;
+	u8 data_valid;
+	u32 data_len;
+	u8 data[QMI_WLFW_MAX_DATA_SIZE_V01];
+	u8 end_valid;
+	u8 end;
+};
+
+#define WLFW_INI_FILE_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6174
+extern struct qmi_elem_info wlfw_ini_file_download_req_msg_v01_ei[];
+
+struct wlfw_ini_file_download_resp_msg_v01 {
+	struct qmi_response_type_v01 resp;
+};
+
+#define WLFW_INI_FILE_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7
+extern struct qmi_elem_info wlfw_ini_file_download_resp_msg_v01_ei[];
+
 #endif