/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * SSH message builder functions.
 *
 * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
 */

#ifndef _SURFACE_AGGREGATOR_SSH_MSGB_H
#define _SURFACE_AGGREGATOR_SSH_MSGB_H

#include <asm/unaligned.h>
#include <linux/types.h>

#include <linux/surface_aggregator/controller.h>
#include <linux/surface_aggregator/serial_hub.h>

/**
 * struct msgbuf - Buffer struct to construct SSH messages.
 * @begin: Pointer to the beginning of the allocated buffer space.
 * @end:   Pointer to the end (one past last element) of the allocated buffer
 *         space.
 * @ptr:   Pointer to the first free element in the buffer.
 */
struct msgbuf {
	u8 *begin;
	u8 *end;
	u8 *ptr;
};

/**
 * msgb_init() - Initialize the given message buffer struct.
 * @msgb: The buffer struct to initialize
 * @ptr:  Pointer to the underlying memory by which the buffer will be backed.
 * @cap:  Size of the underlying memory.
 *
 * Initialize the given message buffer struct using the provided memory as
 * backing.
 */
static inline void msgb_init(struct msgbuf *msgb, u8 *ptr, size_t cap)
{
	msgb->begin = ptr;
	msgb->end = ptr + cap;
	msgb->ptr = ptr;
}

/**
 * msgb_bytes_used() - Return the current number of bytes used in the buffer.
 * @msgb: The message buffer.
 */
static inline size_t msgb_bytes_used(const struct msgbuf *msgb)
{
	return msgb->ptr - msgb->begin;
}

static inline void __msgb_push_u8(struct msgbuf *msgb, u8 value)
{
	*msgb->ptr = value;
	msgb->ptr += sizeof(u8);
}

static inline void __msgb_push_u16(struct msgbuf *msgb, u16 value)
{
	put_unaligned_le16(value, msgb->ptr);
	msgb->ptr += sizeof(u16);
}

/**
 * msgb_push_u16() - Push a u16 value to the buffer.
 * @msgb:  The message buffer.
 * @value: The value to push to the buffer.
 */
static inline void msgb_push_u16(struct msgbuf *msgb, u16 value)
{
	if (WARN_ON(msgb->ptr + sizeof(u16) > msgb->end))
		return;

	__msgb_push_u16(msgb, value);
}

/**
 * msgb_push_syn() - Push SSH SYN bytes to the buffer.
 * @msgb: The message buffer.
 */
static inline void msgb_push_syn(struct msgbuf *msgb)
{
	msgb_push_u16(msgb, SSH_MSG_SYN);
}

/**
 * msgb_push_buf() - Push raw data to the buffer.
 * @msgb: The message buffer.
 * @buf:  The data to push to the buffer.
 * @len:  The length of the data to push to the buffer.
 */
static inline void msgb_push_buf(struct msgbuf *msgb, const u8 *buf, size_t len)
{
	msgb->ptr = memcpy(msgb->ptr, buf, len) + len;
}

/**
 * msgb_push_crc() - Compute CRC and push it to the buffer.
 * @msgb: The message buffer.
 * @buf:  The data for which the CRC should be computed.
 * @len:  The length of the data for which the CRC should be computed.
 */
static inline void msgb_push_crc(struct msgbuf *msgb, const u8 *buf, size_t len)
{
	msgb_push_u16(msgb, ssh_crc(buf, len));
}

/**
 * msgb_push_frame() - Push a SSH message frame header to the buffer.
 * @msgb: The message buffer
 * @ty:   The type of the frame.
 * @len:  The length of the payload of the frame.
 * @seq:  The sequence ID of the frame/packet.
 */
static inline void msgb_push_frame(struct msgbuf *msgb, u8 ty, u16 len, u8 seq)
{
	u8 *const begin = msgb->ptr;

	if (WARN_ON(msgb->ptr + sizeof(struct ssh_frame) > msgb->end))
		return;

	__msgb_push_u8(msgb, ty);	/* Frame type. */
	__msgb_push_u16(msgb, len);	/* Frame payload length. */
	__msgb_push_u8(msgb, seq);	/* Frame sequence ID. */

	msgb_push_crc(msgb, begin, msgb->ptr - begin);
}

/**
 * msgb_push_ack() - Push a SSH ACK frame to the buffer.
 * @msgb: The message buffer
 * @seq:  The sequence ID of the frame/packet to be ACKed.
 */
static inline void msgb_push_ack(struct msgbuf *msgb, u8 seq)
{
	/* SYN. */
	msgb_push_syn(msgb);

	/* ACK-type frame + CRC. */
	msgb_push_frame(msgb, SSH_FRAME_TYPE_ACK, 0x00, seq);

	/* Payload CRC (ACK-type frames do not have a payload). */
	msgb_push_crc(msgb, msgb->ptr, 0);
}

/**
 * msgb_push_nak() - Push a SSH NAK frame to the buffer.
 * @msgb: The message buffer
 */
static inline void msgb_push_nak(struct msgbuf *msgb)
{
	/* SYN. */
	msgb_push_syn(msgb);

	/* NAK-type frame + CRC. */
	msgb_push_frame(msgb, SSH_FRAME_TYPE_NAK, 0x00, 0x00);

	/* Payload CRC (ACK-type frames do not have a payload). */
	msgb_push_crc(msgb, msgb->ptr, 0);
}

/**
 * msgb_push_cmd() - Push a SSH command frame with payload to the buffer.
 * @msgb: The message buffer.
 * @seq:  The sequence ID (SEQ) of the frame/packet.
 * @rqid: The request ID (RQID) of the request contained in the frame.
 * @rqst: The request to wrap in the frame.
 */
static inline void msgb_push_cmd(struct msgbuf *msgb, u8 seq, u16 rqid,
				 const struct ssam_request *rqst)
{
	const u8 type = SSH_FRAME_TYPE_DATA_SEQ;
	u8 *cmd;

	/* SYN. */
	msgb_push_syn(msgb);

	/* Command frame + CRC. */
	msgb_push_frame(msgb, type, sizeof(struct ssh_command) + rqst->length, seq);

	/* Frame payload: Command struct + payload. */
	if (WARN_ON(msgb->ptr + sizeof(struct ssh_command) > msgb->end))
		return;

	cmd = msgb->ptr;

	__msgb_push_u8(msgb, SSH_PLD_TYPE_CMD);		/* Payload type. */
	__msgb_push_u8(msgb, rqst->target_category);	/* Target category. */
	__msgb_push_u8(msgb, rqst->target_id);		/* Target ID (out). */
	__msgb_push_u8(msgb, 0x00);			/* Target ID (in). */
	__msgb_push_u8(msgb, rqst->instance_id);	/* Instance ID. */
	__msgb_push_u16(msgb, rqid);			/* Request ID. */
	__msgb_push_u8(msgb, rqst->command_id);		/* Command ID. */

	/* Command payload. */
	msgb_push_buf(msgb, rqst->payload, rqst->length);

	/* CRC for command struct + payload. */
	msgb_push_crc(msgb, cmd, msgb->ptr - cmd);
}

#endif /* _SURFACE_AGGREGATOR_SSH_MSGB_H */
