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

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

Merge "cnss2: Add API to send WFC mode to WLAN FW"

parents 56677b44 ae5cef9b
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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;
+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>
@@ -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)
+8 −0
Original line number Diff line number Diff line
@@ -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
+10 −0
Original line number Diff line number Diff line
@@ -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 */