// SPDX-License-Identifier: GPL-2.0-only
/*
 * Intel MIC Platform Software Stack (MPSS)
 *
 * Copyright(c) 2014 Intel Corporation.
 *
 * Intel SCIF driver.
 */
#include <linux/circ_buf.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/errno.h>

#include "scif_rb.h"

#define scif_rb_ring_cnt(head, tail, size) CIRC_CNT(head, tail, size)
#define scif_rb_ring_space(head, tail, size) CIRC_SPACE(head, tail, size)

/**
 * scif_rb_init - Initializes the ring buffer
 * @rb: ring buffer
 * @read_ptr: A pointer to the read offset
 * @write_ptr: A pointer to the write offset
 * @rb_base: A pointer to the base of the ring buffer
 * @size: The size of the ring buffer in powers of two
 */
void scif_rb_init(struct scif_rb *rb, u32 *read_ptr, u32 *write_ptr,
		  void *rb_base, u8 size)
{
	rb->rb_base = rb_base;
	rb->size = (1 << size);
	rb->read_ptr = read_ptr;
	rb->write_ptr = write_ptr;
	rb->current_read_offset = *read_ptr;
	rb->current_write_offset = *write_ptr;
}

/* Copies a message to the ring buffer -- handles the wrap around case */
static void memcpy_torb(struct scif_rb *rb, void *header,
			void *msg, u32 size)
{
	u32 size1, size2;

	if (header + size >= rb->rb_base + rb->size) {
		/* Need to call two copies if it wraps around */
		size1 = (u32)(rb->rb_base + rb->size - header);
		size2 = size - size1;
		memcpy_toio((void __iomem __force *)header, msg, size1);
		memcpy_toio((void __iomem __force *)rb->rb_base,
			    msg + size1, size2);
	} else {
		memcpy_toio((void __iomem __force *)header, msg, size);
	}
}

/* Copies a message from the ring buffer -- handles the wrap around case */
static void memcpy_fromrb(struct scif_rb *rb, void *header,
			  void *msg, u32 size)
{
	u32 size1, size2;

	if (header + size >= rb->rb_base + rb->size) {
		/* Need to call two copies if it wraps around */
		size1 = (u32)(rb->rb_base + rb->size - header);
		size2 = size - size1;
		memcpy_fromio(msg, (void __iomem __force *)header, size1);
		memcpy_fromio(msg + size1,
			      (void __iomem __force *)rb->rb_base, size2);
	} else {
		memcpy_fromio(msg, (void __iomem __force *)header, size);
	}
}

/**
 * scif_rb_space - Query space available for writing to the RB
 * @rb: ring buffer
 *
 * Return: size available for writing to RB in bytes.
 */
u32 scif_rb_space(struct scif_rb *rb)
{
	rb->current_read_offset = *rb->read_ptr;
	/*
	 * Update from the HW read pointer only once the peer has exposed the
	 * new empty slot. This barrier is paired with the memory barrier
	 * scif_rb_update_read_ptr()
	 */
	mb();
	return scif_rb_ring_space(rb->current_write_offset,
				  rb->current_read_offset, rb->size);
}

/**
 * scif_rb_write - Write a message to the RB
 * @rb: ring buffer
 * @msg: buffer to send the message.  Must be at least size bytes long
 * @size: the size (in bytes) to be copied to the RB
 *
 * This API does not block if there isn't enough space in the RB.
 * Returns: 0 on success or -ENOMEM on failure
 */
int scif_rb_write(struct scif_rb *rb, void *msg, u32 size)
{
	void *header;

	if (scif_rb_space(rb) < size)
		return -ENOMEM;
	header = rb->rb_base + rb->current_write_offset;
	memcpy_torb(rb, header, msg, size);
	/*
	 * Wait until scif_rb_commit(). Update the local ring
	 * buffer data, not the shared data until commit.
	 */
	rb->current_write_offset =
		(rb->current_write_offset + size) & (rb->size - 1);
	return 0;
}

/**
 * scif_rb_commit - To submit the message to let the peer fetch it
 * @rb: ring buffer
 */
void scif_rb_commit(struct scif_rb *rb)
{
	/*
	 * We must ensure ordering between the all the data committed
	 * previously before we expose the new message to the peer by
	 * updating the write_ptr. This write barrier is paired with
	 * the read barrier in scif_rb_count(..)
	 */
	wmb();
	WRITE_ONCE(*rb->write_ptr, rb->current_write_offset);
#ifdef CONFIG_INTEL_MIC_CARD
	/*
	 * X100 Si bug: For the case where a Core is performing an EXT_WR
	 * followed by a Doorbell Write, the Core must perform two EXT_WR to the
	 * same address with the same data before it does the Doorbell Write.
	 * This way, if ordering is violated for the Interrupt Message, it will
	 * fall just behind the first Posted associated with the first EXT_WR.
	 */
	WRITE_ONCE(*rb->write_ptr, rb->current_write_offset);
#endif
}

/**
 * scif_rb_get - To get next message from the ring buffer
 * @rb: ring buffer
 * @size: Number of bytes to be read
 *
 * Return: NULL if no bytes to be read from the ring buffer, otherwise the
 *	pointer to the next byte
 */
static void *scif_rb_get(struct scif_rb *rb, u32 size)
{
	void *header = NULL;

	if (scif_rb_count(rb, size) >= size)
		header = rb->rb_base + rb->current_read_offset;
	return header;
}

/*
 * scif_rb_get_next - Read from ring buffer.
 * @rb: ring buffer
 * @msg: buffer to hold the message.  Must be at least size bytes long
 * @size: Number of bytes to be read
 *
 * Return: number of bytes read if available bytes are >= size, otherwise
 * returns zero.
 */
u32 scif_rb_get_next(struct scif_rb *rb, void *msg, u32 size)
{
	void *header = NULL;
	int read_size = 0;

	header = scif_rb_get(rb, size);
	if (header) {
		u32 next_cmd_offset =
			(rb->current_read_offset + size) & (rb->size - 1);

		read_size = size;
		rb->current_read_offset = next_cmd_offset;
		memcpy_fromrb(rb, header, msg, size);
	}
	return read_size;
}

/**
 * scif_rb_update_read_ptr
 * @rb: ring buffer
 */
void scif_rb_update_read_ptr(struct scif_rb *rb)
{
	u32 new_offset;

	new_offset = rb->current_read_offset;
	/*
	 * We must ensure ordering between the all the data committed or read
	 * previously before we expose the empty slot to the peer by updating
	 * the read_ptr. This barrier is paired with the memory barrier in
	 * scif_rb_space(..)
	 */
	mb();
	WRITE_ONCE(*rb->read_ptr, new_offset);
#ifdef CONFIG_INTEL_MIC_CARD
	/*
	 * X100 Si Bug: For the case where a Core is performing an EXT_WR
	 * followed by a Doorbell Write, the Core must perform two EXT_WR to the
	 * same address with the same data before it does the Doorbell Write.
	 * This way, if ordering is violated for the Interrupt Message, it will
	 * fall just behind the first Posted associated with the first EXT_WR.
	 */
	WRITE_ONCE(*rb->read_ptr, new_offset);
#endif
}

/**
 * scif_rb_count
 * @rb: ring buffer
 * @size: Number of bytes expected to be read
 *
 * Return: number of bytes that can be read from the RB
 */
u32 scif_rb_count(struct scif_rb *rb, u32 size)
{
	if (scif_rb_ring_cnt(rb->current_write_offset,
			     rb->current_read_offset,
			     rb->size) < size) {
		rb->current_write_offset = *rb->write_ptr;
		/*
		 * Update from the HW write pointer if empty only once the peer
		 * has exposed the new message. This read barrier is paired
		 * with the write barrier in scif_rb_commit(..)
		 */
		smp_rmb();
	}
	return scif_rb_ring_cnt(rb->current_write_offset,
				rb->current_read_offset,
				rb->size);
}
