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

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

Merge "icnss2: Send enter power save after driver suspend"

parents 836dd392 3e55e8fb
Loading
Loading
Loading
Loading
+17 −10
Original line number Diff line number Diff line
@@ -2754,7 +2754,6 @@ EXPORT_SYMBOL(icnss_idle_restart);
int icnss_exit_power_save(struct device *dev)
{
	struct icnss_priv *priv = dev_get_drvdata(dev);
	int ret = 0;

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

@@ -2762,12 +2761,8 @@ int icnss_exit_power_save(struct device *dev)
	    !test_bit(ICNSS_MODE_ON, &priv->state))
		return 0;

	ret = wlfw_exit_power_save_send_msg(priv);
	if (ret) {
		priv->stats.pm_resume_err++;
		return ret;
	}
	return 0;
	return wlfw_power_save_send_msg(priv,
			(enum wlfw_power_save_mode_v01)ICNSS_POWER_SAVE_EXIT);
}
EXPORT_SYMBOL(icnss_exit_power_save);

@@ -3352,12 +3347,18 @@ static int icnss_pm_suspend(struct device *dev)

	if (!priv->ops || !priv->ops->pm_suspend ||
	    !test_bit(ICNSS_DRIVER_PROBED, &priv->state))
		goto out;
		return 0;

	ret = priv->ops->pm_suspend(dev);

out:
	if (ret == 0) {
		if (priv->device_id == WCN6750_DEVICE_ID) {
			ret = wlfw_power_save_send_msg(priv,
				(enum wlfw_power_save_mode_v01)
				ICNSS_POWER_SAVE_ENTER);
			if (ret)
				return priv->ops->pm_resume(dev);
		}
		priv->stats.pm_suspend++;
		set_bit(ICNSS_PM_SUSPEND, &priv->state);
	} else {
@@ -3470,7 +3471,13 @@ static int icnss_pm_runtime_suspend(struct device *dev)

	icnss_pr_vdbg("Runtime suspend\n");
	ret = priv->ops->runtime_suspend(dev);

	if (!ret) {
		ret = wlfw_power_save_send_msg(priv,
				(enum wlfw_power_save_mode_v01)
				ICNSS_POWER_SAVE_ENTER);
		if (ret)
			return priv->ops->runtime_resume(dev);
	}
out:
	return ret;
}
+7 −0
Original line number Diff line number Diff line
@@ -158,6 +158,10 @@ struct icnss_fw_mem {
	unsigned long attrs;
};

enum icnss_power_save_mode {
	ICNSS_POWER_SAVE_ENTER,
	ICNSS_POWER_SAVE_EXIT,
};
struct icnss_stats {
	struct {
		uint32_t posted;
@@ -230,6 +234,9 @@ struct icnss_stats {
	u32 exit_power_save_req;
	u32 exit_power_save_resp;
	u32 exit_power_save_err;
	u32 enter_power_save_req;
	u32 enter_power_save_resp;
	u32 enter_power_save_err;
	u32 soc_wake_req;
	u32 soc_wake_resp;
	u32 soc_wake_err;
+29 −31
Original line number Diff line number Diff line
@@ -341,11 +341,11 @@ int wlfw_device_info_send_msg(struct icnss_priv *priv)
	return ret;
}

int wlfw_exit_power_save_send_msg(struct icnss_priv *priv)
int wlfw_power_save_send_msg(struct icnss_priv *priv,
			     enum wlfw_power_save_mode_v01 mode)
{
	int ret;
	struct wlfw_exit_power_save_req_msg_v01 *req;
	struct wlfw_exit_power_save_resp_msg_v01 *resp;
	struct wlfw_power_save_req_msg_v01 *req;
	struct qmi_txn txn;

	if (!priv)
@@ -354,23 +354,27 @@ int wlfw_exit_power_save_send_msg(struct icnss_priv *priv)
	if (test_bit(ICNSS_FW_DOWN, &priv->state))
		return -EINVAL;

	icnss_pr_dbg("Sending exit power save, state: 0x%lx\n",
		     priv->state);
	if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
	    !test_bit(ICNSS_MODE_ON, &priv->state))
		return 0;

	icnss_pr_dbg("Sending power save mode: %d, state: 0x%lx\n",
		     mode, priv->state);

	req = kzalloc(sizeof(*req), GFP_KERNEL);
	if (!req)
		return -ENOMEM;

	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
	if (!resp) {
		kfree(req);
		return -ENOMEM;
	}
	req->power_save_mode_valid = 1;
	req->power_save_mode = mode;

	if (mode == WLFW_POWER_SAVE_EXIT_V01)
		priv->stats.exit_power_save_req++;
	else
		priv->stats.enter_power_save_req++;

	ret = qmi_txn_init(&priv->qmi, &txn,
			   wlfw_exit_power_save_resp_msg_v01_ei, resp);
			   NULL, NULL);
	if (ret < 0) {
		icnss_qmi_fatal_err("Fail to init txn for exit power save%d\n",
				    ret);
@@ -378,9 +382,9 @@ int wlfw_exit_power_save_send_msg(struct icnss_priv *priv)
	}

	ret = qmi_send_request(&priv->qmi, NULL, &txn,
			       QMI_WLFW_EXIT_POWER_SAVE_REQ_V01,
			       WLFW_EXIT_POWER_SAVE_REQ_MSG_V01_MAX_MSG_LEN,
			       wlfw_exit_power_save_req_msg_v01_ei, req);
			       QMI_WLFW_POWER_SAVE_REQ_V01,
			       WLFW_POWER_SAVE_REQ_MSG_V01_MAX_MSG_LEN,
			       wlfw_power_save_req_msg_v01_ei, req);
	if (ret < 0) {
		qmi_txn_cancel(&txn);
		icnss_qmi_fatal_err("Fail to send exit power save req %d\n",
@@ -388,29 +392,23 @@ int wlfw_exit_power_save_send_msg(struct icnss_priv *priv)
		goto out;
	}

	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
	if (ret < 0) {
		icnss_qmi_fatal_err("Exit power save wait failed with ret %d\n",
				    ret);
		goto out;
	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
		icnss_qmi_fatal_err(
		    "QMI exit power save request rejected,result:%d error:%d\n",
				    resp->resp.result, resp->resp.error);
		ret = -resp->resp.result;
		goto out;
	}
	qmi_txn_cancel(&txn);

	if (mode == WLFW_POWER_SAVE_EXIT_V01)
		priv->stats.exit_power_save_resp++;
	else
		priv->stats.enter_power_save_resp++;

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

out:
	kfree(resp);
	kfree(req);

	if (mode == WLFW_POWER_SAVE_EXIT_V01)
		priv->stats.exit_power_save_err++;
	else
		priv->stats.enter_power_save_err++;
	return ret;
}

+4 −2
Original line number Diff line number Diff line
@@ -129,7 +129,8 @@ int wlfw_qdss_trace_mem_info_send_sync(struct icnss_priv *priv)
	return 0;
}

int wlfw_exit_power_save_send_msg(struct icnss_priv *priv)
int wlfw_power_save_send_msg(struct icnss_priv *priv,
			     enum wlfw_power_save_mode_v01 mode)
{
	return 0;
}
@@ -180,7 +181,8 @@ int wlfw_wlan_mode_send_sync_msg(struct icnss_priv *priv,
				 enum wlfw_driver_mode_enum_v01 mode);
int icnss_wlfw_bdf_dnld_send_sync(struct icnss_priv *priv, u32 bdf_type);
int wlfw_qdss_trace_mem_info_send_sync(struct icnss_priv *priv);
int wlfw_exit_power_save_send_msg(struct icnss_priv *priv);
int wlfw_power_save_send_msg(struct icnss_priv *priv,
			     enum wlfw_power_save_mode_v01 mode);
int icnss_wlfw_get_info_send_sync(struct icnss_priv *priv, int type,
				  void *cmd, int cmd_len);
int wlfw_send_soc_wake_msg(struct icnss_priv *priv,
+142 −5
Original line number Diff line number Diff line
@@ -782,6 +782,24 @@ struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[] = {
		.offset         = offsetof(struct wlfw_ind_register_req_msg_v01,
					   wfc_call_twt_config_enable),
	},
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x22,
		.offset         = offsetof(struct wlfw_ind_register_req_msg_v01,
					   qdss_mem_ready_enable_valid),
	},
	{
		.data_type      = QMI_UNSIGNED_1_BYTE,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x22,
		.offset         = offsetof(struct wlfw_ind_register_req_msg_v01,
					   qdss_mem_ready_enable),
	},
	{
		.data_type      = QMI_EOTI,
		.array_type       = NO_ARRAY,
@@ -1407,6 +1425,42 @@ struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[] = {
		.offset         = offsetof(struct wlfw_cap_resp_msg_v01,
					   eeprom_caldata_read_timeout),
	},
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x1A,
		.offset         = offsetof(struct wlfw_cap_resp_msg_v01,
					   fw_caps_valid),
	},
	{
		.data_type      = QMI_UNSIGNED_8_BYTE,
		.elem_len       = 1,
		.elem_size      = sizeof(u64),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x1A,
		.offset         = offsetof(struct wlfw_cap_resp_msg_v01,
					   fw_caps),
	},
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x1B,
		.offset         = offsetof(struct wlfw_cap_resp_msg_v01,
					   rd_card_chain_cap_valid),
	},
	{
		.data_type      = QMI_SIGNED_4_BYTE_ENUM,
		.elem_len       = 1,
		.elem_size      = sizeof(enum wlfw_rd_card_chain_cap_v01),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x1B,
		.offset         = offsetof(struct wlfw_cap_resp_msg_v01,
					   rd_card_chain_cap),
	},
	{
		.data_type      = QMI_EOTI,
		.array_type       = NO_ARRAY,
@@ -1560,6 +1614,26 @@ struct qmi_elem_info wlfw_bdf_download_resp_msg_v01_ei[] = {
					   resp),
		.ei_array      = qmi_response_type_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_bdf_download_resp_msg_v01,
					   host_bdf_data_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_bdf_download_resp_msg_v01,
					   host_bdf_data),
	},
	{
		.data_type      = QMI_EOTI,
		.array_type       = NO_ARRAY,
@@ -4287,7 +4361,25 @@ struct qmi_elem_info wlfw_soc_wake_resp_msg_v01_ei[] = {
	},
};

struct qmi_elem_info wlfw_exit_power_save_req_msg_v01_ei[] = {
struct qmi_elem_info wlfw_power_save_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_power_save_req_msg_v01,
					   power_save_mode_valid),
	},
	{
		.data_type      = QMI_SIGNED_4_BYTE_ENUM,
		.elem_len       = 1,
		.elem_size      = sizeof(enum wlfw_power_save_mode_v01),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct wlfw_power_save_req_msg_v01,
					   power_save_mode),
	},
	{
		.data_type      = QMI_EOTI,
		.array_type       = NO_ARRAY,
@@ -4295,15 +4387,14 @@ struct qmi_elem_info wlfw_exit_power_save_req_msg_v01_ei[] = {
	},
};

struct qmi_elem_info wlfw_exit_power_save_resp_msg_v01_ei[] = {
struct qmi_elem_info wlfw_power_save_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_exit_power_save_resp_msg_v01,
		.offset         = offsetof(struct wlfw_power_save_resp_msg_v01,
					   resp),
		.ei_array      = qmi_response_type_v01_ei,
	},
@@ -4441,3 +4532,49 @@ struct qmi_elem_info wlfw_wfc_call_twt_config_ind_msg_v01_ei[] = {
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

struct qmi_elem_info wlfw_qdss_mem_ready_ind_msg_v01_ei[] = {
	{
		.data_type      = QMI_EOTI,
		.array_type       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

struct qmi_elem_info wlfw_pcie_gen_switch_req_msg_v01_ei[] = {
	{
		.data_type      = QMI_SIGNED_4_BYTE_ENUM,
		.elem_len       = 1,
		.elem_size      = sizeof(enum wlfw_pcie_gen_speed_v01),
		.array_type       = NO_ARRAY,
		.tlv_type       = 0x01,
		.offset         = offsetof(struct
					   wlfw_pcie_gen_switch_req_msg_v01,
					   pcie_speed),
	},
	{
		.data_type      = QMI_EOTI,
		.array_type       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

struct qmi_elem_info wlfw_pcie_gen_switch_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_pcie_gen_switch_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,
	},
};
Loading