// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2015 - 2021 Intel Corporation */
#include <linux/bitfield.h>
#include <linux/completion.h>
#include <linux/minmax.h>
#include <linux/types.h>
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_pfvf_msg.h"
#include "adf_pfvf_utils.h"
#include "adf_pfvf_vf_msg.h"
#include "adf_pfvf_vf_proto.h"

#define ADF_PFVF_MSG_COLLISION_DETECT_DELAY	10
#define ADF_PFVF_MSG_ACK_DELAY			2
#define ADF_PFVF_MSG_ACK_MAX_RETRY		100

/* How often to retry if there is no response */
#define ADF_PFVF_MSG_RESP_RETRIES	5
#define ADF_PFVF_MSG_RESP_TIMEOUT	(ADF_PFVF_MSG_ACK_DELAY * \
					 ADF_PFVF_MSG_ACK_MAX_RETRY + \
					 ADF_PFVF_MSG_COLLISION_DETECT_DELAY)

/**
 * adf_send_vf2pf_msg() - send VF to PF message
 * @accel_dev:	Pointer to acceleration device
 * @msg:	Message to send
 *
 * This function allows the VF to send a message to the PF.
 *
 * Return: 0 on success, error code otherwise.
 */
int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg)
{
	struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
	u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(0);

	return pfvf_ops->send_msg(accel_dev, msg, pfvf_offset,
				  &accel_dev->vf.vf2pf_lock);
}

/**
 * adf_recv_pf2vf_msg() - receive a PF to VF message
 * @accel_dev:	Pointer to acceleration device
 *
 * This function allows the VF to receive a message from the PF.
 *
 * Return: a valid message on success, zero otherwise.
 */
static struct pfvf_message adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev)
{
	struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
	u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(0);

	return pfvf_ops->recv_msg(accel_dev, pfvf_offset, accel_dev->vf.pf_compat_ver);
}

/**
 * adf_send_vf2pf_req() - send VF2PF request message
 * @accel_dev:	Pointer to acceleration device.
 * @msg:	Request message to send
 * @resp:	Returned PF response
 *
 * This function sends a message that requires a response from the VF to the PF
 * and waits for a reply.
 *
 * Return: 0 on success, error code otherwise.
 */
int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
		       struct pfvf_message *resp)
{
	unsigned long timeout = msecs_to_jiffies(ADF_PFVF_MSG_RESP_TIMEOUT);
	unsigned int retries = ADF_PFVF_MSG_RESP_RETRIES;
	int ret;

	reinit_completion(&accel_dev->vf.msg_received);

	/* Send request from VF to PF */
	do {
		ret = adf_send_vf2pf_msg(accel_dev, msg);
		if (ret) {
			dev_err(&GET_DEV(accel_dev),
				"Failed to send request msg to PF\n");
			return ret;
		}

		/* Wait for response, if it times out retry */
		ret = wait_for_completion_timeout(&accel_dev->vf.msg_received,
						  timeout);
		if (ret) {
			if (likely(resp))
				*resp = accel_dev->vf.response;

			/* Once copied, set to an invalid value */
			accel_dev->vf.response.type = 0;

			return 0;
		}

		dev_err(&GET_DEV(accel_dev), "PFVF response message timeout\n");
	} while (--retries);

	return -EIO;
}

static int adf_vf2pf_blkmsg_data_req(struct adf_accel_dev *accel_dev, bool crc,
				     u8 *type, u8 *data)
{
	struct pfvf_message req = { 0 };
	struct pfvf_message resp = { 0 };
	u8 blk_type;
	u8 blk_byte;
	u8 msg_type;
	u8 max_data;
	int err;

	/* Convert the block type to {small, medium, large} size category */
	if (*type <= ADF_VF2PF_SMALL_BLOCK_TYPE_MAX) {
		msg_type = ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ;
		blk_type = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, *type);
		blk_byte = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, *data);
		max_data = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX;
	} else if (*type <= ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) {
		msg_type = ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ;
		blk_type = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK,
				      *type - ADF_VF2PF_SMALL_BLOCK_TYPE_MAX);
		blk_byte = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, *data);
		max_data = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX;
	} else if (*type <= ADF_VF2PF_LARGE_BLOCK_TYPE_MAX) {
		msg_type = ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ;
		blk_type = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK,
				      *type - ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX);
		blk_byte = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, *data);
		max_data = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX;
	} else {
		dev_err(&GET_DEV(accel_dev), "Invalid message type %u\n", *type);
		return -EINVAL;
	}

	/* Sanity check */
	if (*data > max_data) {
		dev_err(&GET_DEV(accel_dev),
			"Invalid byte %s %u for message type %u\n",
			crc ? "count" : "index", *data, *type);
		return -EINVAL;
	}

	/* Build the block message */
	req.type = msg_type;
	req.data = blk_type | blk_byte | FIELD_PREP(ADF_VF2PF_BLOCK_CRC_REQ_MASK, crc);

	err = adf_send_vf2pf_req(accel_dev, req, &resp);
	if (err)
		return err;

	*type = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp.data);
	*data = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp.data);

	return 0;
}

static int adf_vf2pf_blkmsg_get_byte(struct adf_accel_dev *accel_dev, u8 type,
				     u8 index, u8 *data)
{
	int ret;

	ret = adf_vf2pf_blkmsg_data_req(accel_dev, false, &type, &index);
	if (ret < 0)
		return ret;

	if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_DATA)) {
		dev_err(&GET_DEV(accel_dev),
			"Unexpected BLKMSG response type %u, byte 0x%x\n",
			type, index);
		return -EFAULT;
	}

	*data = index;
	return 0;
}

static int adf_vf2pf_blkmsg_get_crc(struct adf_accel_dev *accel_dev, u8 type,
				    u8 bytes, u8 *crc)
{
	int ret;

	/* The count of bytes refers to a length, however shift it to a 0-based
	 * count to avoid overflows. Thus, a request for 0 bytes is technically
	 * valid.
	 */
	--bytes;

	ret = adf_vf2pf_blkmsg_data_req(accel_dev, true, &type, &bytes);
	if (ret < 0)
		return ret;

	if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_CRC)) {
		dev_err(&GET_DEV(accel_dev),
			"Unexpected CRC BLKMSG response type %u, crc 0x%x\n",
			type, bytes);
		return  -EFAULT;
	}

	*crc = bytes;
	return 0;
}

/**
 * adf_send_vf2pf_blkmsg_req() - retrieve block message
 * @accel_dev:	Pointer to acceleration VF device.
 * @type:	The block message type, see adf_pfvf_msg.h for allowed values
 * @buffer:	input buffer where to place the received data
 * @buffer_len:	buffer length as input, the amount of written bytes on output
 *
 * Request a message of type 'type' over the block message transport.
 * This function will send the required amount block message requests and
 * return the overall content back to the caller through the provided buffer.
 * The buffer should be large enough to contain the requested message type,
 * otherwise the response will be truncated.
 *
 * Return: 0 on success, error code otherwise.
 */
int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type,
			      u8 *buffer, unsigned int *buffer_len)
{
	unsigned int index;
	unsigned int msg_len;
	int ret;
	u8 remote_crc;
	u8 local_crc;

	if (unlikely(type > ADF_VF2PF_LARGE_BLOCK_TYPE_MAX)) {
		dev_err(&GET_DEV(accel_dev), "Invalid block message type %d\n",
			type);
		return -EINVAL;
	}

	if (unlikely(*buffer_len < ADF_PFVF_BLKMSG_HEADER_SIZE)) {
		dev_err(&GET_DEV(accel_dev),
			"Buffer size too small for a block message\n");
		return -EINVAL;
	}

	ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
					ADF_PFVF_BLKMSG_VER_BYTE,
					&buffer[ADF_PFVF_BLKMSG_VER_BYTE]);
	if (unlikely(ret))
		return ret;

	if (unlikely(!buffer[ADF_PFVF_BLKMSG_VER_BYTE])) {
		dev_err(&GET_DEV(accel_dev),
			"Invalid version 0 received for block request %u", type);
		return -EFAULT;
	}

	ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
					ADF_PFVF_BLKMSG_LEN_BYTE,
					&buffer[ADF_PFVF_BLKMSG_LEN_BYTE]);
	if (unlikely(ret))
		return ret;

	if (unlikely(!buffer[ADF_PFVF_BLKMSG_LEN_BYTE])) {
		dev_err(&GET_DEV(accel_dev),
			"Invalid size 0 received for block request %u", type);
		return -EFAULT;
	}

	/* We need to pick the minimum since there is no way to request a
	 * specific version. As a consequence any scenario is possible:
	 * - PF has a newer (longer) version which doesn't fit in the buffer
	 * - VF expects a newer (longer) version, so we must not ask for
	 *   bytes in excess
	 * - PF and VF share the same version, no problem
	 */
	msg_len = ADF_PFVF_BLKMSG_HEADER_SIZE + buffer[ADF_PFVF_BLKMSG_LEN_BYTE];
	msg_len = min(*buffer_len, msg_len);

	/* Get the payload */
	for (index = ADF_PFVF_BLKMSG_HEADER_SIZE; index < msg_len; index++) {
		ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, index,
						&buffer[index]);
		if (unlikely(ret))
			return ret;
	}

	ret = adf_vf2pf_blkmsg_get_crc(accel_dev, type, msg_len, &remote_crc);
	if (unlikely(ret))
		return ret;

	local_crc = adf_pfvf_calc_blkmsg_crc(buffer, msg_len);
	if (unlikely(local_crc != remote_crc)) {
		dev_err(&GET_DEV(accel_dev),
			"CRC error on msg type %d. Local %02X, remote %02X\n",
			type, local_crc, remote_crc);
		return -EIO;
	}

	*buffer_len = msg_len;
	return 0;
}

static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev,
				 struct pfvf_message msg)
{
	switch (msg.type) {
	case ADF_PF2VF_MSGTYPE_RESTARTING:
		dev_dbg(&GET_DEV(accel_dev), "Restarting message received from PF\n");

		adf_pf2vf_handle_pf_restarting(accel_dev);
		return false;
	case ADF_PF2VF_MSGTYPE_RESTARTED:
		dev_dbg(&GET_DEV(accel_dev), "Restarted message received from PF\n");
		return true;
	case ADF_PF2VF_MSGTYPE_FATAL_ERROR:
		dev_err(&GET_DEV(accel_dev), "Fatal error received from PF\n");
		return true;
	case ADF_PF2VF_MSGTYPE_VERSION_RESP:
	case ADF_PF2VF_MSGTYPE_BLKMSG_RESP:
	case ADF_PF2VF_MSGTYPE_RP_RESET_RESP:
		dev_dbg(&GET_DEV(accel_dev),
			"Response Message received from PF (type 0x%.4x, data 0x%.4x)\n",
			msg.type, msg.data);
		accel_dev->vf.response = msg;
		complete(&accel_dev->vf.msg_received);
		return true;
	default:
		dev_err(&GET_DEV(accel_dev),
			"Unknown message from PF (type 0x%.4x, data: 0x%.4x)\n",
			msg.type, msg.data);
	}

	return false;
}

bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev)
{
	struct pfvf_message msg;

	msg = adf_recv_pf2vf_msg(accel_dev);
	if (msg.type)  /* Invalid or no message */
		return adf_handle_pf2vf_msg(accel_dev, msg);

	/* No replies for PF->VF messages at present */

	return true;
}

/**
 * adf_enable_vf2pf_comms() - Function enables communication from vf to pf
 *
 * @accel_dev:	Pointer to acceleration device virtual function.
 *
 * Return: 0 on success, error code otherwise.
 */
int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
{
	int ret;

	adf_pfvf_crc_init();
	adf_enable_pf2vf_interrupts(accel_dev);

	ret = adf_vf2pf_request_version(accel_dev);
	if (ret)
		return ret;

	ret = adf_vf2pf_get_capabilities(accel_dev);
	if (ret)
		return ret;

	ret = adf_vf2pf_get_ring_to_svc(accel_dev);

	return ret;
}
EXPORT_SYMBOL_GPL(adf_enable_vf2pf_comms);
