Loading drivers/net/wireless/cnss2/main.c +21 −0 Original line number Diff line number Diff line Loading @@ -3134,6 +3134,27 @@ cnss_is_converged_dt(struct cnss_plat_data *plat_priv) return of_property_read_bool(plat_priv->plat_dev->dev.of_node, "qcom,converged-dt"); } int cnss_set_wfc_mode(struct device *dev, struct cnss_wfc_cfg cfg) { struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); int ret = 0; if (!plat_priv) return -ENODEV; /* If IMS server is connected, return success without QMI send */ if (test_bit(CNSS_IMS_CONNECTED, &plat_priv->driver_state)) { cnss_pr_dbg("Ignore host request as IMS server is connected"); return ret; } ret = cnss_wlfw_send_host_wfc_call_status(plat_priv, cfg); return ret; } EXPORT_SYMBOL(cnss_set_wfc_mode); static int cnss_probe(struct platform_device *plat_dev) { int ret = 0; Loading drivers/net/wireless/cnss2/qmi.c +67 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/firmware.h> Loading Loading @@ -1957,6 +1957,72 @@ int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv) return ret; } int cnss_wlfw_send_host_wfc_call_status(struct cnss_plat_data *plat_priv, struct cnss_wfc_cfg cfg) { struct wlfw_wfc_call_status_req_msg_v01 *req; struct wlfw_wfc_call_status_resp_msg_v01 *resp; struct qmi_txn txn; int ret = 0; if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) { cnss_pr_err("Drop host WFC indication as FW not initialized\n"); return -EINVAL; } req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; resp = kzalloc(sizeof(*resp), GFP_KERNEL); if (!resp) { kfree(req); return -ENOMEM; } req->wfc_call_active_valid = 1; req->wfc_call_active = cfg.mode; cnss_pr_dbg("CNSS->FW: WFC_CALL_REQ: state: 0x%lx\n", plat_priv->driver_state); ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn, wlfw_wfc_call_status_resp_msg_v01_ei, resp); if (ret < 0) { cnss_pr_err("CNSS->FW: WFC_CALL_REQ: QMI Txn Init: Err %d\n", ret); goto out; } cnss_pr_dbg("Send WFC Mode: %d\n", cfg.mode); ret = qmi_send_request(&plat_priv->qmi_wlfw, NULL, &txn, QMI_WLFW_WFC_CALL_STATUS_REQ_V01, WLFW_WFC_CALL_STATUS_REQ_MSG_V01_MAX_MSG_LEN, wlfw_wfc_call_status_req_msg_v01_ei, req); if (ret < 0) { qmi_txn_cancel(&txn); cnss_pr_err("CNSS->FW: WFC_CALL_REQ: QMI Send Err: %d\n", ret); goto out; } ret = qmi_txn_wait(&txn, QMI_WLFW_TIMEOUT_JF); if (ret < 0) { cnss_pr_err("FW->CNSS: WFC_CALL_RSP: QMI Wait Err: %d\n", ret); goto out; } if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { cnss_pr_err("FW->CNSS: WFC_CALL_RSP: Result: %d Err: %d\n", resp->resp.result, resp->resp.error); ret = -EINVAL; goto out; } ret = 0; out: kfree(req); kfree(resp); return ret; } static int cnss_wlfw_wfc_call_status_send_sync (struct cnss_plat_data *plat_priv, const struct ims_private_service_wfc_call_status_ind_msg_v01 *ind_msg) Loading drivers/net/wireless/cnss2/qmi.h +8 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,8 @@ int cnss_wlfw_qdss_data_send_sync(struct cnss_plat_data *plat_priv, char *file_n u32 total_size); int wlfw_qdss_trace_send_start(struct cnss_plat_data *plat_priv); int wlfw_qdss_trace_send_stop(struct cnss_plat_data *plat_priv, unsigned long long option); int cnss_wlfw_send_host_wfc_call_status(struct cnss_plat_data *plat_priv, struct cnss_wfc_cfg cfg); #else #define QMI_WLFW_TIMEOUT_MS 10000 Loading Loading @@ -285,6 +287,12 @@ int wlfw_qdss_trace_send_stop(struct cnss_plat_data *plat_priv, unsigned long lo { return 0; } int cnss_wlfw_send_host_wfc_call_status(struct cnss_plat_data *plat_priv, struct cnss_wfc_cfg cfg) { return 0; } #endif /* CONFIG_CNSS2_QMI */ #ifdef CONFIG_CNSS2_DEBUG Loading include/net/cnss2.h +10 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,15 @@ enum cnss_bus_event_type { BUS_EVENT_INVALID = 0xFFFF, }; enum cnss_wfc_mode { CNSS_WFC_MODE_OFF, CNSS_WFC_MODE_ON, }; struct cnss_wfc_cfg { enum cnss_wfc_mode mode; }; struct cnss_hang_event { void *hang_event_data; u16 hang_event_data_len; Loading Loading @@ -281,4 +290,5 @@ extern int cnss_get_mem_segment_info(enum cnss_remote_mem_type type, extern int cnss_send_buffer_to_afcmem(struct device *dev, char *afcdb, uint32_t len, uint8_t slotid); extern int cnss_reset_afcmem(struct device *dev, uint8_t slotid); extern int cnss_set_wfc_mode(struct device *dev, struct cnss_wfc_cfg cfg); #endif /* _NET_CNSS2_H */ Loading
drivers/net/wireless/cnss2/main.c +21 −0 Original line number Diff line number Diff line Loading @@ -3134,6 +3134,27 @@ cnss_is_converged_dt(struct cnss_plat_data *plat_priv) return of_property_read_bool(plat_priv->plat_dev->dev.of_node, "qcom,converged-dt"); } int cnss_set_wfc_mode(struct device *dev, struct cnss_wfc_cfg cfg) { struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); int ret = 0; if (!plat_priv) return -ENODEV; /* If IMS server is connected, return success without QMI send */ if (test_bit(CNSS_IMS_CONNECTED, &plat_priv->driver_state)) { cnss_pr_dbg("Ignore host request as IMS server is connected"); return ret; } ret = cnss_wlfw_send_host_wfc_call_status(plat_priv, cfg); return ret; } EXPORT_SYMBOL(cnss_set_wfc_mode); static int cnss_probe(struct platform_device *plat_dev) { int ret = 0; Loading
drivers/net/wireless/cnss2/qmi.c +67 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/firmware.h> Loading Loading @@ -1957,6 +1957,72 @@ int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv) return ret; } int cnss_wlfw_send_host_wfc_call_status(struct cnss_plat_data *plat_priv, struct cnss_wfc_cfg cfg) { struct wlfw_wfc_call_status_req_msg_v01 *req; struct wlfw_wfc_call_status_resp_msg_v01 *resp; struct qmi_txn txn; int ret = 0; if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) { cnss_pr_err("Drop host WFC indication as FW not initialized\n"); return -EINVAL; } req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; resp = kzalloc(sizeof(*resp), GFP_KERNEL); if (!resp) { kfree(req); return -ENOMEM; } req->wfc_call_active_valid = 1; req->wfc_call_active = cfg.mode; cnss_pr_dbg("CNSS->FW: WFC_CALL_REQ: state: 0x%lx\n", plat_priv->driver_state); ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn, wlfw_wfc_call_status_resp_msg_v01_ei, resp); if (ret < 0) { cnss_pr_err("CNSS->FW: WFC_CALL_REQ: QMI Txn Init: Err %d\n", ret); goto out; } cnss_pr_dbg("Send WFC Mode: %d\n", cfg.mode); ret = qmi_send_request(&plat_priv->qmi_wlfw, NULL, &txn, QMI_WLFW_WFC_CALL_STATUS_REQ_V01, WLFW_WFC_CALL_STATUS_REQ_MSG_V01_MAX_MSG_LEN, wlfw_wfc_call_status_req_msg_v01_ei, req); if (ret < 0) { qmi_txn_cancel(&txn); cnss_pr_err("CNSS->FW: WFC_CALL_REQ: QMI Send Err: %d\n", ret); goto out; } ret = qmi_txn_wait(&txn, QMI_WLFW_TIMEOUT_JF); if (ret < 0) { cnss_pr_err("FW->CNSS: WFC_CALL_RSP: QMI Wait Err: %d\n", ret); goto out; } if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { cnss_pr_err("FW->CNSS: WFC_CALL_RSP: Result: %d Err: %d\n", resp->resp.result, resp->resp.error); ret = -EINVAL; goto out; } ret = 0; out: kfree(req); kfree(resp); return ret; } static int cnss_wlfw_wfc_call_status_send_sync (struct cnss_plat_data *plat_priv, const struct ims_private_service_wfc_call_status_ind_msg_v01 *ind_msg) Loading
drivers/net/wireless/cnss2/qmi.h +8 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,8 @@ int cnss_wlfw_qdss_data_send_sync(struct cnss_plat_data *plat_priv, char *file_n u32 total_size); int wlfw_qdss_trace_send_start(struct cnss_plat_data *plat_priv); int wlfw_qdss_trace_send_stop(struct cnss_plat_data *plat_priv, unsigned long long option); int cnss_wlfw_send_host_wfc_call_status(struct cnss_plat_data *plat_priv, struct cnss_wfc_cfg cfg); #else #define QMI_WLFW_TIMEOUT_MS 10000 Loading Loading @@ -285,6 +287,12 @@ int wlfw_qdss_trace_send_stop(struct cnss_plat_data *plat_priv, unsigned long lo { return 0; } int cnss_wlfw_send_host_wfc_call_status(struct cnss_plat_data *plat_priv, struct cnss_wfc_cfg cfg) { return 0; } #endif /* CONFIG_CNSS2_QMI */ #ifdef CONFIG_CNSS2_DEBUG Loading
include/net/cnss2.h +10 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,15 @@ enum cnss_bus_event_type { BUS_EVENT_INVALID = 0xFFFF, }; enum cnss_wfc_mode { CNSS_WFC_MODE_OFF, CNSS_WFC_MODE_ON, }; struct cnss_wfc_cfg { enum cnss_wfc_mode mode; }; struct cnss_hang_event { void *hang_event_data; u16 hang_event_data_len; Loading Loading @@ -281,4 +290,5 @@ extern int cnss_get_mem_segment_info(enum cnss_remote_mem_type type, extern int cnss_send_buffer_to_afcmem(struct device *dev, char *afcdb, uint32_t len, uint8_t slotid); extern int cnss_reset_afcmem(struct device *dev, uint8_t slotid); extern int cnss_set_wfc_mode(struct device *dev, struct cnss_wfc_cfg cfg); #endif /* _NET_CNSS2_H */