Loading drivers/soc/qcom/icnss.c +5 −0 Original line number Diff line number Diff line Loading @@ -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); Loading drivers/soc/qcom/icnss_qmi.c +63 −0 Original line number Diff line number Diff line Loading @@ -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; Loading drivers/soc/qcom/icnss_qmi.h +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 Loading Loading @@ -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) { Loading Loading @@ -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, Loading drivers/soc/qcom/wlan_firmware_service_v01.c +44 −0 Original line number Diff line number Diff line Loading @@ -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, }, }; drivers/soc/qcom/wlan_firmware_service_v01.h +15 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading
drivers/soc/qcom/icnss.c +5 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
drivers/soc/qcom/icnss_qmi.c +63 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
drivers/soc/qcom/icnss_qmi.h +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 Loading Loading @@ -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) { Loading Loading @@ -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, Loading
drivers/soc/qcom/wlan_firmware_service_v01.c +44 −0 Original line number Diff line number Diff line Loading @@ -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, }, };
drivers/soc/qcom/wlan_firmware_service_v01.h +15 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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