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

Commit 64ec4599 authored by Anurag Chouhan's avatar Anurag Chouhan Committed by Yuanyuan Liu
Browse files

icnss: Add QMI command to indicate graceful shutdown to FW



Add a QMI command to indicate graceful shutdown to the FW

Change-Id: Icb598853496d03419031e83d2a8bc8c923cf2a8e
CRs-Fixed: 2227790
Signed-off-by: default avatarAnurag Chouhan <achouhan@codeaurora.org>
Signed-off-by: default avatarYuanyuan Liu <yuanliu@codeaurora.org>
parent 45933fac
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1205,6 +1205,11 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
	if (code != SUBSYS_BEFORE_SHUTDOWN)
		return NOTIFY_OK;

	if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed) {
		if (wlfw_send_modem_shutdown_msg(priv))
			icnss_pr_dbg("Fail to send modem shutdown Indication\n");
	}

	if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) {
		set_bit(ICNSS_FW_DOWN, &priv->state);
		icnss_ignore_fw_timeout(true);
+63 −0
Original line number Diff line number Diff line
@@ -552,6 +552,69 @@ int wlfw_wlan_cfg_send_sync_msg(struct icnss_priv *priv,
	return ret;
}

int wlfw_send_modem_shutdown_msg(struct icnss_priv *priv)
{
	int ret;
	struct wlfw_shutdown_req_msg_v01 *req;
	struct wlfw_shutdown_resp_msg_v01 *resp;
	struct qmi_txn txn;

	if (!priv)
		return -ENODEV;

	icnss_pr_dbg("Sending modem shutdown request, state: 0x%lx\n",
		     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->shutdown_valid = 1;
	req->shutdown = 1;

	ret = qmi_txn_init(&priv->qmi, &txn,
			   wlfw_shutdown_resp_msg_v01_ei, resp);

	if (ret < 0) {
		icnss_pr_err("Fail to init txn for shutdown resp %d\n",
			     ret);
		goto out;
	}

	ret = qmi_send_request(&priv->qmi, NULL, &txn,
			       QMI_WLFW_SHUTDOWN_REQ_V01,
			       WLFW_SHUTDOWN_REQ_MSG_V01_MAX_MSG_LEN,
			       wlfw_shutdown_req_msg_v01_ei, req);
	if (ret < 0) {
		qmi_txn_cancel(&txn);
		icnss_pr_err("Fail to send Shutdown req %d\n", ret);
		goto out;
	}

	ret = qmi_txn_wait(&txn, WLFW_TIMEOUT);
	if (ret < 0) {
		icnss_pr_err("Shutdown resp wait failed with ret %d\n",
			     ret);
		goto out;
	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
		icnss_pr_err("QMI modem shutdown request rejected result:%d error:%d\n",
			     resp->resp.result, resp->resp.error);
		ret = -resp->resp.result;
		goto out;
	}

out:
	kfree(resp);
	kfree(req);
	return ret;
}

int wlfw_ini_send_sync_msg(struct icnss_priv *priv, uint8_t fw_log_mode)
{
	int ret;
+6 −2
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -50,7 +50,10 @@ static inline int wlfw_rejuvenate_ack_send_sync_msg(struct icnss_priv *priv)
	return 0;
}
static inline void icnss_ignore_fw_timeout(bool ignore) {}

static int wlfw_send_modem_shutdown_msg(struct icnss_priv *priv)
{
	return 0;
}
static inline int wlfw_ini_send_sync_msg(struct icnss_priv *priv,
		uint8_t fw_log_mode)
{
@@ -103,6 +106,7 @@ int wlfw_dynamic_feature_mask_send_sync_msg(struct icnss_priv *priv,
int icnss_clear_server(struct icnss_priv *priv);
int wlfw_rejuvenate_ack_send_sync_msg(struct icnss_priv *priv);
void icnss_ignore_fw_timeout(bool ignore);
int wlfw_send_modem_shutdown_msg(struct icnss_priv *priv);
int wlfw_ini_send_sync_msg(struct icnss_priv *priv, uint8_t fw_log_mode);
int wlfw_athdiag_read_send_sync_msg(struct icnss_priv *priv,
					   uint32_t offset, uint32_t mem_type,
+44 −0
Original line number Diff line number Diff line
@@ -2283,3 +2283,47 @@ struct qmi_elem_info wlfw_xo_cal_ind_msg_v01_ei[] = {
	},
};

struct qmi_elem_info wlfw_shutdown_req_msg_v01_ei[] = {
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.is_array       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct wlfw_shutdown_req_msg_v01,
					   shutdown_valid),
	},
	{
		.data_type      = QMI_UNSIGNED_1_BYTE,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.is_array       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct wlfw_shutdown_req_msg_v01,
					   shutdown),
	},
	{
		.data_type      = QMI_EOTI,
		.is_array       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

struct qmi_elem_info wlfw_shutdown_resp_msg_v01_ei[] = {
	{
		.data_type      = QMI_STRUCT,
		.elem_len       = 1,
		.elem_size      = sizeof(struct qmi_response_type_v01),
		.is_array       = NO_ARRAY,
		.tlv_type       = 0x02,
		.offset         = offsetof(struct wlfw_shutdown_resp_msg_v01,
					   resp),
		.ei_array      = qmi_response_type_v01_ei,
	},
	{
		.data_type      = QMI_EOTI,
		.is_array       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};
+15 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#define QMI_WLFW_XO_CAL_IND_V01 0x003D
#define QMI_WLFW_INI_RESP_V01 0x002F
#define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026
#define QMI_WLFW_SHUTDOWN_RESP_V01 0x0043
#define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033
#define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028
#define QMI_WLFW_HOST_CAP_RESP_V01 0x0034
@@ -57,6 +58,7 @@
#define QMI_WLFW_CAP_RESP_V01 0x0024
#define QMI_WLFW_REJUVENATE_ACK_REQ_V01 0x003A
#define QMI_WLFW_ATHDIAG_READ_RESP_V01 0x0030
#define QMI_WLFW_SHUTDOWN_REQ_V01 0x0043
#define QMI_WLFW_VBATT_REQ_V01 0x0032
#define QMI_WLFW_MAC_ADDR_REQ_V01 0x0033
#define QMI_WLFW_RESPOND_MEM_RESP_V01 0x0036
@@ -608,4 +610,17 @@ struct wlfw_xo_cal_ind_msg_v01 {
#define WLFW_XO_CAL_IND_MSG_V01_MAX_MSG_LEN 4
extern struct qmi_elem_info wlfw_xo_cal_ind_msg_v01_ei[];

struct wlfw_shutdown_req_msg_v01 {
	u8 shutdown_valid;
	u8 shutdown;
};
#define WLFW_SHUTDOWN_REQ_MSG_V01_MAX_MSG_LEN 4
extern struct qmi_elem_info wlfw_shutdown_req_msg_v01_ei[];

struct wlfw_shutdown_resp_msg_v01 {
	struct qmi_response_type_v01 resp;
};
#define WLFW_SHUTDOWN_RESP_MSG_V01_MAX_MSG_LEN 7
extern struct qmi_elem_info wlfw_shutdown_resp_msg_v01_ei[];

#endif