Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * For transports using message passing.
0004  *
0005  * Derived from shm.c.
0006  *
0007  * Copyright (C) 2019-2021 ARM Ltd.
0008  * Copyright (C) 2020-2021 OpenSynergy GmbH
0009  */
0010 
0011 #include <linux/types.h>
0012 
0013 #include "common.h"
0014 
0015 /*
0016  * struct scmi_msg_payld - Transport SDU layout
0017  *
0018  * The SCMI specification requires all parameters, message headers, return
0019  * arguments or any protocol data to be expressed in little endian format only.
0020  */
0021 struct scmi_msg_payld {
0022     __le32 msg_header;
0023     __le32 msg_payload[];
0024 };
0025 
0026 /**
0027  * msg_command_size() - Actual size of transport SDU for command.
0028  *
0029  * @xfer: message which core has prepared for sending
0030  *
0031  * Return: transport SDU size.
0032  */
0033 size_t msg_command_size(struct scmi_xfer *xfer)
0034 {
0035     return sizeof(struct scmi_msg_payld) + xfer->tx.len;
0036 }
0037 
0038 /**
0039  * msg_response_size() - Maximum size of transport SDU for response.
0040  *
0041  * @xfer: message which core has prepared for sending
0042  *
0043  * Return: transport SDU size.
0044  */
0045 size_t msg_response_size(struct scmi_xfer *xfer)
0046 {
0047     return sizeof(struct scmi_msg_payld) + sizeof(__le32) + xfer->rx.len;
0048 }
0049 
0050 /**
0051  * msg_tx_prepare() - Set up transport SDU for command.
0052  *
0053  * @msg: transport SDU for command
0054  * @xfer: message which is being sent
0055  */
0056 void msg_tx_prepare(struct scmi_msg_payld *msg, struct scmi_xfer *xfer)
0057 {
0058     msg->msg_header = cpu_to_le32(pack_scmi_header(&xfer->hdr));
0059     if (xfer->tx.buf)
0060         memcpy(msg->msg_payload, xfer->tx.buf, xfer->tx.len);
0061 }
0062 
0063 /**
0064  * msg_read_header() - Read SCMI header from transport SDU.
0065  *
0066  * @msg: transport SDU
0067  *
0068  * Return: SCMI header
0069  */
0070 u32 msg_read_header(struct scmi_msg_payld *msg)
0071 {
0072     return le32_to_cpu(msg->msg_header);
0073 }
0074 
0075 /**
0076  * msg_fetch_response() - Fetch response SCMI payload from transport SDU.
0077  *
0078  * @msg: transport SDU with response
0079  * @len: transport SDU size
0080  * @xfer: message being responded to
0081  */
0082 void msg_fetch_response(struct scmi_msg_payld *msg, size_t len,
0083             struct scmi_xfer *xfer)
0084 {
0085     size_t prefix_len = sizeof(*msg) + sizeof(msg->msg_payload[0]);
0086 
0087     xfer->hdr.status = le32_to_cpu(msg->msg_payload[0]);
0088     xfer->rx.len = min_t(size_t, xfer->rx.len,
0089                  len >= prefix_len ? len - prefix_len : 0);
0090 
0091     /* Take a copy to the rx buffer.. */
0092     memcpy(xfer->rx.buf, &msg->msg_payload[1], xfer->rx.len);
0093 }
0094 
0095 /**
0096  * msg_fetch_notification() - Fetch notification payload from transport SDU.
0097  *
0098  * @msg: transport SDU with notification
0099  * @len: transport SDU size
0100  * @max_len: maximum SCMI payload size to fetch
0101  * @xfer: notification message
0102  */
0103 void msg_fetch_notification(struct scmi_msg_payld *msg, size_t len,
0104                 size_t max_len, struct scmi_xfer *xfer)
0105 {
0106     xfer->rx.len = min_t(size_t, max_len,
0107                  len >= sizeof(*msg) ? len - sizeof(*msg) : 0);
0108 
0109     /* Take a copy to the rx buffer.. */
0110     memcpy(xfer->rx.buf, msg->msg_payload, xfer->rx.len);
0111 }