cnss2: Add API to send WFC mode to WLAN FW

Add and export API to host driver to send WFC(WiFi Calling)
mode to WLAN FW.

Change-Id: I92d3d0baad9afc6fdf66f66b847a4e8a90a54341
CRs-Fixed: 3346550
Signed-off-by: Krupali Dhanvijay <quic_kdhanvij@quicinc.com>
This commit is contained in:
Krupali Dhanvijay 2023-01-16 20:39:50 +05:30
parent 41978afa6c
commit ae5cef9b7e
4 changed files with 106 additions and 1 deletions

View File

@ -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;

View File

@ -1,6 +1,6 @@
// 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>
@ -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)

View File

@ -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
@ -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

View File

@ -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;
@ -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 */