summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixelBot AutoMerger <android-nexus-securitybot@system.gserviceaccount.com>2022-12-04 22:07:18 -0800
committerSecurityBot <android-nexus-securitybot@system.gserviceaccount.com>2022-12-04 22:07:19 -0800
commit0bd17973b7a3a14f4ef06bb87ac0e531b4c5c236 (patch)
tree908753d0a68dcdb7f3fb55e0396256151be77d96
parent769ec5e9eb820c7183e72c4512d8adde4f875e24 (diff)
parent0574a2be8d7e444de441ada5c429ddc91bb6e644 (diff)
downloadcnss2-0bd17973b7a3a14f4ef06bb87ac0e531b4c5c236.tar.gz
Merge android13-gs-pixel-5.10-tm-qpr2 into android13-gs-pixel-5.10-tm-qpr3
SBMerger: 478053055 Change-Id: Ifbb242d3dfc7c3122e651a5632789887521989d4 Signed-off-by: SecurityBot <android-nexus-securitybot@system.gserviceaccount.com>
-rw-r--r--cnss2/main.c20
-rw-r--r--cnss2/qmi.c68
-rw-r--r--cnss2/qmi.h8
-rw-r--r--inc/cnss2.h10
4 files changed, 106 insertions, 0 deletions
diff --git a/cnss2/main.c b/cnss2/main.c
index acc5b93..4ce0cf1 100644
--- a/cnss2/main.c
+++ b/cnss2/main.c
@@ -3570,6 +3570,26 @@ cnss_use_nv_mac(struct cnss_plat_data *plat_priv)
"use-nv-mac");
}
+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;
diff --git a/cnss2/qmi.c b/cnss2/qmi.c
index 1572c94..d37d11f 100644
--- a/cnss2/qmi.c
+++ b/cnss2/qmi.c
@@ -2121,6 +2121,74 @@ out:
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)
diff --git a/cnss2/qmi.h b/cnss2/qmi.h
index 1fa4bb2..cbf562f 100644
--- a/cnss2/qmi.h
+++ b/cnss2/qmi.h
@@ -86,6 +86,8 @@ int cnss_wlfw_cal_report_req_send_sync(struct cnss_plat_data *plat_priv,
u32 cal_file_download_size);
int cnss_wlfw_ini_file_send_sync(struct cnss_plat_data *plat_priv,
enum wlfw_ini_file_type_v01 file_type);
+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
@@ -307,6 +309,12 @@ int cnss_wlfw_ini_file_send_sync(struct cnss_plat_data *plat_priv,
{
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
diff --git a/inc/cnss2.h b/inc/cnss2.h
index e4dcbb4..44e2f57 100644
--- a/inc/cnss2.h
+++ b/inc/cnss2.h
@@ -98,6 +98,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;
@@ -293,4 +302,5 @@ extern int cnss_get_mem_segment_info(enum cnss_remote_mem_type type,
extern int cnss_get_pci_slot(struct device *dev);
extern int cnss_pci_get_reg_dump(struct device *dev, uint8_t *buffer,
uint32_t len);
+extern int cnss_set_wfc_mode(struct device *dev, struct cnss_wfc_cfg cfg);
#endif /* _NET_CNSS2_H */