From 5139e8a7dfa9c4e76bfc80d760b131b212a1464c Mon Sep 17 00:00:00 2001 From: Kaushal Hooda Date: Tue, 20 Jul 2021 17:31:18 +0530 Subject: [PATCH] net: qrtr: Prevent wakeups using service id based filter Filter data from adsp by using service id so that it will not have wake up capable packets. Service id can be read from DT file and wakeup could be avoided for corresponding packets. Change-Id: Ibbb5f74bb153cdd333f8037b498c366d4f2ac5f8 Signed-off-by: Sarannya S Signed-off-by: Kaushal Hooda --- net/qrtr/haven.c | 2 +- net/qrtr/mhi.c | 2 +- net/qrtr/mhi_dev.c | 2 +- net/qrtr/qrtr.c | 27 ++++++++++++++++++++++++--- net/qrtr/qrtr.h | 4 +++- net/qrtr/smd.c | 16 ++++++++++++++-- 6 files changed, 44 insertions(+), 9 deletions(-) diff --git a/net/qrtr/haven.c b/net/qrtr/haven.c index 1358bba65a27..ecd4bf48ee32 100644 --- a/net/qrtr/haven.c +++ b/net/qrtr/haven.c @@ -612,7 +612,7 @@ static int qrtr_haven_probe(struct platform_device *pdev) INIT_WORK(&qdev->work, qrtr_haven_retry_work); qdev->ep.xmit = qrtr_haven_send; - ret = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NET_ID_AUTO, false); + ret = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NET_ID_AUTO, false, NULL); if (ret) goto register_fail; diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c index 519bd2186d85..c9377d28d890 100644 --- a/net/qrtr/mhi.c +++ b/net/qrtr/mhi.c @@ -176,7 +176,7 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev, dev_set_drvdata(&mhi_dev->dev, qdev); - rc = qrtr_endpoint_register(&qdev->ep, net_id, rt); + rc = qrtr_endpoint_register(&qdev->ep, net_id, rt, NULL); if (rc) return rc; diff --git a/net/qrtr/mhi_dev.c b/net/qrtr/mhi_dev.c index f93600092745..5710c4454731 100644 --- a/net/qrtr/mhi_dev.c +++ b/net/qrtr/mhi_dev.c @@ -182,7 +182,7 @@ static void qrtr_mhi_dev_state_cb(struct mhi_dev_client_cb_data *cb_data) return; } - rc = qrtr_endpoint_register(&qep->ep, qep->net_id, qep->rt); + rc = qrtr_endpoint_register(&qep->ep, qep->net_id, qep->rt, NULL); if (rc) { dev_err(qep->dev, "register failed %d\n", rc); qrtr_mhi_dev_close_channels(qep); diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 79072ab6c44f..569e95262be1 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -142,6 +142,7 @@ static DEFINE_SPINLOCK(qrtr_port_lock); #define QRTR_BACKUP_HI_SIZE SZ_16K #define QRTR_BACKUP_LO_NUM 20 #define QRTR_BACKUP_LO_SIZE SZ_1K + static struct sk_buff_head qrtr_backup_lo; static struct sk_buff_head qrtr_backup_hi; static struct work_struct qrtr_backup_work; @@ -190,6 +191,8 @@ struct qrtr_node { struct wakeup_source *ws; void *ilc; + + u32 nonwake_svc[MAX_NON_WAKE_SVC_LEN]; }; struct qrtr_tx_flow_waiter { @@ -838,7 +841,9 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) size_t size; unsigned int ver; size_t hdrlen; - int errcode; + int errcode, i; + bool wake = true; + int svc_id; if (len == 0 || len & 3) return -EINVAL; @@ -938,9 +943,22 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) goto err; /* Force wakeup for all packets except for sensors */ - if (node->nid != 9) + if (node->nid != 9 && node->nid != 5) pm_wakeup_ws_event(node->ws, qrtr_wakeup_ms, true); + if (node->nid == 5) { + svc_id = qrtr_get_service_id(cb->src_node, cb->src_port); + if (svc_id > 0) { + for (i = 0; i < MAX_NON_WAKE_SVC_LEN; i++) { + if (svc_id == node->nonwake_svc[i]) { + wake = false; + break; + } + } + } + if (wake) + pm_wakeup_ws_event(node->ws, qrtr_wakeup_ms, true); + } qrtr_port_put(ipc); } @@ -1149,7 +1167,7 @@ static void qrtr_hello_work(struct kthread_work *work) * The specified endpoint must have the xmit function pointer set on call. */ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id, - bool rt) + bool rt, u32 *svc_arr) { struct qrtr_node *node; struct sched_param param = {.sched_priority = 1}; @@ -1180,6 +1198,9 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id, if (rt) sched_setscheduler(node->task, SCHED_FIFO, ¶m); + if (svc_arr) + memcpy(node->nonwake_svc, svc_arr, MAX_NON_WAKE_SVC_LEN * sizeof(int)); + mutex_init(&node->qrtr_tx_lock); INIT_RADIX_TREE(&node->qrtr_tx_flow, GFP_KERNEL); init_waitqueue_head(&node->resume_tx); diff --git a/net/qrtr/qrtr.h b/net/qrtr/qrtr.h index 8784f5eecb34..449028c2ec93 100644 --- a/net/qrtr/qrtr.h +++ b/net/qrtr/qrtr.h @@ -12,6 +12,8 @@ struct sk_buff; #define QRTR_DEL_PROC_MAGIC 0xe111 +#define MAX_NON_WAKE_SVC_LEN 5 + /** * struct qrtr_endpoint - endpoint handle * @xmit: Callback for outgoing packets @@ -27,7 +29,7 @@ struct qrtr_endpoint { }; int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id, - bool rt); + bool rt, u32 *svc_arr); void qrtr_endpoint_unregister(struct qrtr_endpoint *ep); diff --git a/net/qrtr/smd.c b/net/qrtr/smd.c index 632717cc9996..45626f99dad6 100644 --- a/net/qrtr/smd.c +++ b/net/qrtr/smd.c @@ -64,7 +64,8 @@ static int qcom_smd_qrtr_probe(struct rpmsg_device *rpdev) struct qrtr_smd_dev *qdev; u32 net_id; bool rt; - int rc; + int rc, size; + u32 *svc_arr = NULL; pr_info("%s:Entered\n", __func__); qdev = devm_kzalloc(&rpdev->dev, sizeof(*qdev), GFP_KERNEL); @@ -81,7 +82,18 @@ static int qcom_smd_qrtr_probe(struct rpmsg_device *rpdev) rt = of_property_read_bool(rpdev->dev.of_node, "qcom,low-latency"); - rc = qrtr_endpoint_register(&qdev->ep, net_id, rt); + size = of_property_count_u32_elems(rpdev->dev.of_node, "qcom,non-wake-svc"); + + if (size > 0) { + if (size > MAX_NON_WAKE_SVC_LEN) + size = MAX_NON_WAKE_SVC_LEN; + svc_arr = kmalloc_array(size, sizeof(u32), GFP_KERNEL); + + of_property_read_u32_array(rpdev->dev.of_node, "qcom,non-wake-svc", + svc_arr, size); + } + rc = qrtr_endpoint_register(&qdev->ep, net_id, rt, svc_arr); + if (rc) return rc;