Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp1414580ybb; Sat, 11 Apr 2020 02:54:59 -0700 (PDT) X-Google-Smtp-Source: APiQypLxlncJwd0QSX6KPGhEG8jxYXaUPu6be0zIrrUqRZHjWwxJkgoLEpH4vWuDApL2UobXGW6T X-Received: by 2002:a0c:dd05:: with SMTP id u5mr3275707qvk.41.1586598899118; Sat, 11 Apr 2020 02:54:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586598899; cv=none; d=google.com; s=arc-20160816; b=fVQ/YMDSKkETKxeUiAlrI5EPFdCuU/idRdCzb6/SMfyGlMHaBV/3dayLqI7bLc0o0Z 6VKmGKuEGcH9DQnjmiTgHshY/vtiJKEIVbb3MK4j6CQKxcHKBnc4e4XHIFeMtDMrBeM/ 5JnAKY0pQSAHIwB1VdyUxbDDhFuz4TOgNR3gNND6dwq1Qe4HV/3JILIKvldgKCFLaAJx 0tsU4sHerzeGT1auis56WZiAophr//hC1apaP8AvVglDXMnRbSQbya9n1u1j+CUvKdRP Nf4uRjH9/uYSVnTiWW0w3o4Av2gKHk6VPiHGY6i3nMWz//HwAS5/VdgzMrm6Nfyz5VcI mmwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=iepWa2mYLevrJR2RtvLpkkCwsq3cEKje/f7iJHCBbOE=; b=uWLO958opGR1qvp54V0cM87Lz7VQlrURB9BaqsWTyMJlUdxdyj46w551SdNIS6wW3E DU8vJ/KPKU/BJzf3le6sAddebgheYofR22kAWbbG8lXGV9ftIashiUpBNWkiFOP80Cd1 jJ54s50/zHukwjivaL24yNAs83LhlDdkf299EBQmj3nWgA4CCQSwUSI95yL9XAFPojzq tokl8jFT9PKMAi3PcDI9qw+yEwRPPOLOlSBjZ56rnQCe3HWlfRvla6iDK2r1YGggqesm YzQHfHTKk8iwisvWVxM7V7eCtMaiy87NMnisUMYwHYJ4iqTGKUIhE3q1onX3HR6CC3kA Xs8w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f19si2450773qve.155.2020.04.11.02.54.45; Sat, 11 Apr 2020 02:54:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726107AbgDKJxx (ORCPT + 99 others); Sat, 11 Apr 2020 05:53:53 -0400 Received: from m17618.mail.qiye.163.com ([59.111.176.18]:64382 "EHLO m17618.mail.qiye.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725945AbgDKJxx (ORCPT ); Sat, 11 Apr 2020 05:53:53 -0400 Received: from ubuntu.localdomain (unknown [58.251.74.227]) by m17618.mail.qiye.163.com (Hmail) with ESMTPA id 662504E1537; Sat, 11 Apr 2020 17:53:45 +0800 (CST) From: Wang Wenhu To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org Cc: Wang Wenhu Subject: [PATCH 2/3] driver: rpmon: qmi message version 01 Date: Sat, 11 Apr 2020 02:53:00 -0700 Message-Id: <20200411095301.18780-3-wenhu.wang@vivo.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200411095301.18780-1-wenhu.wang@vivo.com> References: <20200411095301.18780-1-wenhu.wang@vivo.com> X-HM-Spam-Status: e1kfGhgUHx5ZQUtXWQgYFAkeWUFZSVVOTklCQkJMSE9DTENOT1lXWShZQU hPN1dZLVlBSVdZCQ4XHghZQVk1NCk2OjckKS43PlkG X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6Nhg6Ejo5STg6EhQjPzkVIkJJ SgoKCjBVSlVKTkNNTkJDQ0lOTU1CVTMWGhIXVQweFRMOVQwaFRw7DRINFFUYFBZFWVdZEgtZQVlO Q1VJTkpVTE9VSUlMWVdZCAFZQUpKTkxINwY+ X-HM-Tid: 0a7168a8ce2e9376kuws662504e1537 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Implements a RPMON_QMI message set for a certain rpmon service. RPMON_QMI defines its message types modularly. Each rpmon service binds to a message set and introduced as a module. This version 1.0 message set could be used for connection checking of remote processors. RPMON_QMI messages depend on QCOM_QMI_HELPERS and should be updated together with QMI related modules. Signed-off-by: Wang Wenhu --- drivers/rpmon/Kconfig | 13 ++ drivers/rpmon/Makefile | 1 + drivers/rpmon/rpmon_qmi.h | 77 ++++++++++ drivers/rpmon/rpmon_qmi_msg_v1.c | 240 +++++++++++++++++++++++++++++++ 4 files changed, 331 insertions(+) create mode 100644 drivers/rpmon/rpmon_qmi.h create mode 100644 drivers/rpmon/rpmon_qmi_msg_v1.c diff --git a/drivers/rpmon/Kconfig b/drivers/rpmon/Kconfig index 505d263e0867..4118d4fab433 100644 --- a/drivers/rpmon/Kconfig +++ b/drivers/rpmon/Kconfig @@ -23,4 +23,17 @@ config RPMON Currently RPMON_QMI is available which uses QMI infrastructures on Qualcomm SoC Platforms. +config RPMON_QMI_MSG_V1 + tristate "RPMON QMI Message Version 1.0" + depends on RPMON + depends on QCOM_QMI_HELPERS + help + Implements a RPMON_QMI message set for a certain rpmon service. + RPMON_QMI defines its message types modularly. Each rpmon service + binds to a message set and introduced as a module. This version 1.0 + message set could be used for connection checking of remote processors. + + RPMON_QMI messages depend on QCOM_QMI_HELPERS and should be updated + together with QMI related modules. + endmenu diff --git a/drivers/rpmon/Makefile b/drivers/rpmon/Makefile index b0f0ec4ecc30..25f468a73a20 100644 --- a/drivers/rpmon/Makefile +++ b/drivers/rpmon/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_RPMON) += rpmon.o +obj-$(CONFIG_RPMON_QMI_MSG_V1) += rpmon_qmi_msg_v1.o diff --git a/drivers/rpmon/rpmon_qmi.h b/drivers/rpmon/rpmon_qmi.h new file mode 100644 index 000000000000..f6e7cfc97a3f --- /dev/null +++ b/drivers/rpmon/rpmon_qmi.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Vivo Communication Technology Co. Ltd. + * Copyright (C) 2020 Wang Wenhu + * All rights reserved. + */ + +#ifndef RPMON_QMI_INTERFACE_H +#define RPMON_QMI_INTERFACE_H + +#define RP_NAME_LEN 255 +#define RPQMI_BUF_SIZE 4096 +#define QMI_TLV_TL_SIZE 3 + +enum rpmon_exec_result { + RPMON_EXEC_SUCCESS = 0, + RPMON_EXEC_FAILURE = 1, +}; + +struct rpmon_register_req { + uint8_t name_valid; + char name[RP_NAME_LEN + 1]; + uint8_t timeout_valid; + u32 timeout; +}; + +struct rpmon_conn_indication { + char placeholder; +}; + +struct rpmon_conn_check_resp { + uint8_t result_valid; + struct qmi_response_type_v01 result; +}; + +struct rpmon_response { + struct qmi_response_type_v01 resp; +}; + +struct rpmon_qmi_device { + struct list_head list; + struct sockaddr_qrtr addr; + u32 timeout; + u32 flag; + struct ratelimit_state ratelimit; + + atomic_t checks; + atomic_t reports; + + struct rpmon_info *info; + struct rpmon_qmi *rqmi; +}; + +struct rpmon_qmi { + struct rpmon_info *info; + struct qmi_handle qmi; + struct qmi_service *svc; + struct qmi_ops *ops; + struct qmi_msg_handler *handlers; + int (*sendmsg)(const struct rpmon_qmi_device *rdev, + const void *data, + u32 len); +}; + +/* rpqmi message types currently supported. */ +enum rpmon_qmi_msg_type { + RPQMI_MSG_REGISTER = 0, + RPQMI_MSG_CONNCHK_RESP, + RPQMI_MSG_MAX, +}; + +int rpmon_qmi_handle_init(struct rpmon_qmi *rqmi, + void (*cb)(enum rpmon_qmi_msg_type type, + struct sockaddr_qrtr *sq, + const void *msg)); + +#endif /* RPMON_QMI_INTERFACE_H */ diff --git a/drivers/rpmon/rpmon_qmi_msg_v1.c b/drivers/rpmon/rpmon_qmi_msg_v1.c new file mode 100644 index 000000000000..10d38d8133b0 --- /dev/null +++ b/drivers/rpmon/rpmon_qmi_msg_v1.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Vivo Communication Technology Co. Ltd. + * Copyright (C) 2020 Wang Wenhu + * All rights reserved. + * + * RPMON An implementation of remote processor monitor freamwork + * for platforms that multi-processors exists. RPMON is implemented + * with chardev and sysfs class as interfaces to communicate with + * the user level. It supports different communication interfaces + * added modularly with remote processors. Currently QMI implementation + * is available, and this file implements the message type v1. + * + * RPMON could be used to detect the stabilities of remote processors, + * collect any kinds of information you are interested with, take + * actions like connection status check, and so on. Enhancements can + * be made upon current implementation. + */ + +#include +#include +#include "rpmon_qmi.h" + +#define RPMON_SVC_ID_V01 0x3c +#define RPMON_SVC_VER_V01 0x01 +#define RPMON_SVC_INS_V01 0x00 + +#define RPMON_CONN_REQ_MSG_ID_VO1 0x20 +#define RPMON_CONN_RESP_MSG_ID_VO1 0x20 +#define RPMON_CONN_IND_MSG_ID_V01 0x21 +#define RPMON_EXEC_COMP_REQ_MSG_ID_V01 0x22 +#define RPMON_EXEC_COMP_RESP_MSG_ID_V01 0x22 + +static struct qmi_elem_info register_req_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct rpmon_register_req, + name_valid), + }, + { + .data_type = QMI_STRING, + .elem_len = RP_NAME_LEN, + .elem_size = sizeof(char), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct rpmon_register_req, + name), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct rpmon_register_req, + timeout_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct rpmon_register_req, + timeout), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static struct qmi_elem_info conn_check_resp_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct rpmon_conn_check_resp, + result_valid), + }, + { + .data_type = QMI_SIGNED_4_BYTE_ENUM, + .elem_len = 1, + .elem_size = sizeof(enum rpmon_exec_result), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct rpmon_conn_check_resp, + result), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static struct qmi_elem_info conn_indication_v01_ei[] = { + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static struct qmi_elem_info response_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof( + struct rpmon_response, + resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static void (*msg_callback)(enum rpmon_qmi_msg_type type, + struct sockaddr_qrtr *sq, + const void *msg); + +static int rpmon_qmi_sendmsg_v1(const struct rpmon_qmi_device *rdev, + const void *data, + u32 len) +{ + int ret; + struct sockaddr_qrtr sq; + + memcpy(&sq, &rdev->addr, sizeof(sq)); + + ret = qmi_send_indication(&rdev->rqmi->qmi, &sq, + RPMON_CONN_IND_MSG_ID_V01, + QMI_TLV_TL_SIZE, + conn_indication_v01_ei, NULL); + if (ret < 0) + pr_err("Error %d send indication failed", ret); + + return ret; +} + +static void rpmon_qmi_recv_register_req_v1(struct qmi_handle *qmi, + struct sockaddr_qrtr *sq, + struct qmi_txn *txn, + const void *msg) +{ + struct rpmon_response resp; + int ret; + + resp.resp.result = QMI_RESULT_SUCCESS_V01; + resp.resp.error = QMI_ERR_NONE_V01; + ret = qmi_send_response(qmi, sq, txn, + RPMON_CONN_RESP_MSG_ID_VO1, + sizeof(resp.resp) + QMI_TLV_TL_SIZE * 2, + response_v01_ei, + &resp.resp); + if (ret < 0) + pr_err("Error %d send respons failed", ret); + + if (msg_callback) + msg_callback(RPQMI_MSG_REGISTER, sq, msg); +} + +void rpmon_qmi_recv_conn_check_resp_v1(struct qmi_handle *qmi, + struct sockaddr_qrtr *sq, + struct qmi_txn *txn, + const void *msg) +{ + struct rpmon_response resp; + int ret; + + resp.resp.result = QMI_RESULT_SUCCESS_V01; + resp.resp.error = QMI_ERR_NONE_V01; + ret = qmi_send_response(qmi, sq, txn, + RPMON_EXEC_COMP_REQ_MSG_ID_V01, + sizeof(resp.resp) + QMI_TLV_TL_SIZE * 2, + response_v01_ei, + &resp.resp); + if (ret < 0) + pr_err("Error %d send respons failed", ret); + + if (msg_callback) + msg_callback(RPQMI_MSG_CONNCHK_RESP, sq, msg); +} + +static struct qmi_msg_handler rpmon_qmi_msg_handlers_v01[] = { + { + .type = QMI_REQUEST, + .msg_id = RPMON_CONN_REQ_MSG_ID_VO1, + .ei = register_req_v01_ei, + .decoded_size = sizeof(struct rpmon_register_req), + .fn = rpmon_qmi_recv_register_req_v1, + }, + { + .type = QMI_REQUEST, + .msg_id = RPMON_EXEC_COMP_REQ_MSG_ID_V01, + .ei = conn_check_resp_v01_ei, + .decoded_size = sizeof(struct rpmon_conn_check_resp), + .fn = rpmon_qmi_recv_conn_check_resp_v1, + }, +}; + +static struct qmi_service rpmon_qmi_svc = { + .service = RPMON_SVC_ID_V01, + .version = RPMON_SVC_VER_V01, + .instance = RPMON_SVC_INS_V01, +}; + +int rpmon_qmi_handle_init(struct rpmon_qmi *rqmi, + void (*cb)(enum rpmon_qmi_msg_type type, + struct sockaddr_qrtr *sq, + const void *msg)) +{ + rqmi->svc = &rpmon_qmi_svc; + rqmi->handlers = rpmon_qmi_msg_handlers_v01; + rqmi->sendmsg = rpmon_qmi_sendmsg_v1; + + if (cb) + msg_callback = cb; + else + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL(rpmon_qmi_handle_init); + +MODULE_AUTHOR("Wang Wenhu"); +MODULE_LICENSE("GPL v2"); -- 2.17.1