diff options
author | Karthikeyan Ramasubramanian <kramasub@codeaurora.org> | 2016-02-03 14:20:26 -0700 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:08:08 -0700 |
commit | cdb2ce4239f547fe7c680f875a07dcb7dd39c3a7 (patch) | |
tree | e6d784b7fafa72cb84a82d4bc5d4e4da44cc2851 /include/linux | |
parent | 7c45a7bcfa99ef68330b208566955e64221331de (diff) |
soc: qcom: Add snapshot of QMI
This snapshot is taken as of msm-3.18 commit e70ad0cd (Promotion of
kernel.lnx.3.18-151201.)
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/qmi_encdec.h | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/include/linux/qmi_encdec.h b/include/linux/qmi_encdec.h new file mode 100644 index 000000000000..66c3d84485ed --- /dev/null +++ b/include/linux/qmi_encdec.h @@ -0,0 +1,184 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _QMI_ENCDEC_H_ +#define _QMI_ENCDEC_H_ + +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/list.h> +#include <linux/socket.h> +#include <linux/gfp.h> + +#define QMI_REQUEST_CONTROL_FLAG 0x00 +#define QMI_RESPONSE_CONTROL_FLAG 0x02 +#define QMI_INDICATION_CONTROL_FLAG 0x04 +#define QMI_HEADER_SIZE 7 + +/** + * elem_type - Enum to identify the data type of elements in a data + * structure. + */ +enum elem_type { + QMI_OPT_FLAG = 1, + QMI_DATA_LEN, + QMI_UNSIGNED_1_BYTE, + QMI_UNSIGNED_2_BYTE, + QMI_UNSIGNED_4_BYTE, + QMI_UNSIGNED_8_BYTE, + QMI_SIGNED_2_BYTE_ENUM, + QMI_SIGNED_4_BYTE_ENUM, + QMI_STRUCT, + QMI_STRING, + QMI_EOTI, +}; + +/** + * array_type - Enum to identify if an element in a data structure is + * an array. If so, then is it a static length array or a + * variable length array. + */ +enum array_type { + NO_ARRAY = 0, + STATIC_ARRAY = 1, + VAR_LEN_ARRAY = 2, +}; + +/** + * elem_info - Data structure to specify information about an element + * in a data structure. An array of this data structure + * can be used to specify info about a complex data + * structure to be encoded/decoded. + * + * @data_type: Data type of this element. + * @elem_len: Array length of this element, if an array. + * @elem_size: Size of a single instance of this data type. + * @is_array: Array type of this element. + * @tlv_type: QMI message specific type to identify which element + * is present in an incoming message. + * @offset: To identify the address of the first instance of this + * element in the data structure. + * @ei_array: Array to provide information about the nested structure + * within a data structure to be encoded/decoded. + */ +struct elem_info { + enum elem_type data_type; + uint32_t elem_len; + uint32_t elem_size; + enum array_type is_array; + uint8_t tlv_type; + uint32_t offset; + struct elem_info *ei_array; +}; + +/** + * @msg_desc - Describe about the main/outer structure to be + * encoded/decoded. + * + * @max_msg_len: Maximum possible length of the QMI message. + * @ei_array: Array to provide information about a data structure. + */ +struct msg_desc { + uint16_t msg_id; + int max_msg_len; + struct elem_info *ei_array; +}; + +struct qmi_header { + unsigned char cntl_flag; + uint16_t txn_id; + uint16_t msg_id; + uint16_t msg_len; +} __attribute__((__packed__)); + +static inline void encode_qmi_header(unsigned char *buf, + unsigned char cntl_flag, uint16_t txn_id, + uint16_t msg_id, uint16_t msg_len) +{ + struct qmi_header *hdr = (struct qmi_header *)buf; + + hdr->cntl_flag = cntl_flag; + hdr->txn_id = txn_id; + hdr->msg_id = msg_id; + hdr->msg_len = msg_len; +} + +static inline void decode_qmi_header(unsigned char *buf, + unsigned char *cntl_flag, uint16_t *txn_id, + uint16_t *msg_id, uint16_t *msg_len) +{ + struct qmi_header *hdr = (struct qmi_header *)buf; + + *cntl_flag = hdr->cntl_flag; + *txn_id = hdr->txn_id; + *msg_id = hdr->msg_id; + *msg_len = hdr->msg_len; +} + +#ifdef CONFIG_QMI_ENCDEC +/** + * qmi_kernel_encode() - Encode to QMI message wire format + * @desc: Pointer to structure descriptor. + * @out_buf: Buffer to hold the encoded QMI message. + * @out_buf_len: Length of the out buffer. + * @in_c_struct: C Structure to be encoded. + * + * @return: size of encoded message on success, < 0 on error. + */ +int qmi_kernel_encode(struct msg_desc *desc, + void *out_buf, uint32_t out_buf_len, + void *in_c_struct); + +/** + * qmi_kernel_decode() - Decode to C Structure format + * @desc: Pointer to structure descriptor. + * @out_c_struct: Buffer to hold the decoded C structure. + * @in_buf: Buffer containg the QMI message to be decoded. + * @in_buf_len: Length of the incoming QMI message. + * + * @return: 0 on success, < 0 on error. + */ +int qmi_kernel_decode(struct msg_desc *desc, void *out_c_struct, + void *in_buf, uint32_t in_buf_len); + +/** + * qmi_verify_max_msg_len() - Verify the maximum length of a QMI message + * @desc: Pointer to structure descriptor. + * + * @return: true if the maximum message length embedded in structure + * descriptor matches the calculated value, else false. + */ +bool qmi_verify_max_msg_len(struct msg_desc *desc); + +#else +static inline int qmi_kernel_encode(struct msg_desc *desc, + void *out_buf, uint32_t out_buf_len, + void *in_c_struct) +{ + return -EOPNOTSUPP; +} + +static inline int qmi_kernel_decode(struct msg_desc *desc, + void *out_c_struct, + void *in_buf, uint32_t in_buf_len) +{ + return -EOPNOTSUPP; +} + +static inline bool qmi_verify_max_msg_len(struct msg_desc *desc) +{ + return false; +} +#endif + +#endif |