// SPDX-License-Identifier: GPL-2.01/*2* For transports using message passing.3*4* Derived from shm.c.5*6* Copyright (C) 2019-2024 ARM Ltd.7* Copyright (C) 2020-2021 OpenSynergy GmbH8*/910#include <linux/types.h>1112#include "common.h"1314/*15* struct scmi_msg_payld - Transport SDU layout16*17* The SCMI specification requires all parameters, message headers, return18* arguments or any protocol data to be expressed in little endian format only.19*/20struct scmi_msg_payld {21__le32 msg_header;22__le32 msg_payload[];23};2425/**26* msg_command_size() - Actual size of transport SDU for command.27*28* @xfer: message which core has prepared for sending29*30* Return: transport SDU size.31*/32static size_t msg_command_size(struct scmi_xfer *xfer)33{34return sizeof(struct scmi_msg_payld) + xfer->tx.len;35}3637/**38* msg_response_size() - Maximum size of transport SDU for response.39*40* @xfer: message which core has prepared for sending41*42* Return: transport SDU size.43*/44static size_t msg_response_size(struct scmi_xfer *xfer)45{46return sizeof(struct scmi_msg_payld) + sizeof(__le32) + xfer->rx.len;47}4849/**50* msg_tx_prepare() - Set up transport SDU for command.51*52* @msg: transport SDU for command53* @xfer: message which is being sent54*/55static void msg_tx_prepare(struct scmi_msg_payld *msg, struct scmi_xfer *xfer)56{57msg->msg_header = cpu_to_le32(pack_scmi_header(&xfer->hdr));58if (xfer->tx.buf)59memcpy(msg->msg_payload, xfer->tx.buf, xfer->tx.len);60}6162/**63* msg_read_header() - Read SCMI header from transport SDU.64*65* @msg: transport SDU66*67* Return: SCMI header68*/69static u32 msg_read_header(struct scmi_msg_payld *msg)70{71return le32_to_cpu(msg->msg_header);72}7374/**75* msg_fetch_response() - Fetch response SCMI payload from transport SDU.76*77* @msg: transport SDU with response78* @len: transport SDU size79* @xfer: message being responded to80*/81static void msg_fetch_response(struct scmi_msg_payld *msg,82size_t len, struct scmi_xfer *xfer)83{84size_t prefix_len = sizeof(*msg) + sizeof(msg->msg_payload[0]);8586xfer->hdr.status = le32_to_cpu(msg->msg_payload[0]);87xfer->rx.len = min_t(size_t, xfer->rx.len,88len >= prefix_len ? len - prefix_len : 0);8990/* Take a copy to the rx buffer.. */91memcpy(xfer->rx.buf, &msg->msg_payload[1], xfer->rx.len);92}9394/**95* msg_fetch_notification() - Fetch notification payload from transport SDU.96*97* @msg: transport SDU with notification98* @len: transport SDU size99* @max_len: maximum SCMI payload size to fetch100* @xfer: notification message101*/102static void msg_fetch_notification(struct scmi_msg_payld *msg, size_t len,103size_t max_len, struct scmi_xfer *xfer)104{105xfer->rx.len = min_t(size_t, max_len,106len >= sizeof(*msg) ? len - sizeof(*msg) : 0);107108/* Take a copy to the rx buffer.. */109memcpy(xfer->rx.buf, msg->msg_payload, xfer->rx.len);110}111112static const struct scmi_message_operations scmi_msg_ops = {113.tx_prepare = msg_tx_prepare,114.command_size = msg_command_size,115.response_size = msg_response_size,116.read_header = msg_read_header,117.fetch_response = msg_fetch_response,118.fetch_notification = msg_fetch_notification,119};120121const struct scmi_message_operations *scmi_message_operations_get(void)122{123return &scmi_msg_ops;124}125126127