// SPDX-License-Identifier: MIT
/*
 * Copyright © 2023 Intel Corporation
 */

#include <linux/bitfield.h>
#include <linux/delay.h>

#include <drm/drm_managed.h>

#include <kunit/static_stub.h>
#include <kunit/test-bug.h>

#include "abi/guc_actions_sriov_abi.h"
#include "abi/guc_relay_actions_abi.h"
#include "abi/guc_relay_communication_abi.h"

#include "xe_assert.h"
#include "xe_device.h"
#include "xe_gt.h"
#include "xe_gt_sriov_printk.h"
#include "xe_guc.h"
#include "xe_guc_ct.h"
#include "xe_guc_hxg_helpers.h"
#include "xe_guc_relay.h"
#include "xe_guc_relay_types.h"
#include "xe_sriov.h"

/*
 * How long should we wait for the response?
 * XXX this value is subject for the profiling.
 */
#define RELAY_TIMEOUT_MSEC	(2500)

static void relays_worker_fn(struct work_struct *w);

static struct xe_guc *relay_to_guc(struct xe_guc_relay *relay)
{
	return container_of(relay, struct xe_guc, relay);
}

static struct xe_guc_ct *relay_to_ct(struct xe_guc_relay *relay)
{
	return &relay_to_guc(relay)->ct;
}

static struct xe_gt *relay_to_gt(struct xe_guc_relay *relay)
{
	return guc_to_gt(relay_to_guc(relay));
}

static struct xe_device *relay_to_xe(struct xe_guc_relay *relay)
{
	return gt_to_xe(relay_to_gt(relay));
}

#define relay_assert(relay, condition)	xe_gt_assert(relay_to_gt(relay), condition)
#define relay_notice(relay, msg...)	xe_gt_sriov_notice(relay_to_gt(relay), "relay: " msg)
#define relay_debug(relay, msg...)	xe_gt_sriov_dbg_verbose(relay_to_gt(relay), "relay: " msg)

static int relay_get_totalvfs(struct xe_guc_relay *relay)
{
	struct xe_device *xe = relay_to_xe(relay);
	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);

	KUNIT_STATIC_STUB_REDIRECT(relay_get_totalvfs, relay);
	return IS_SRIOV_VF(xe) ? 0 : pci_sriov_get_totalvfs(pdev);
}

static bool relay_is_ready(struct xe_guc_relay *relay)
{
	return mempool_initialized(&relay->pool);
}

static u32 relay_get_next_rid(struct xe_guc_relay *relay)
{
	u32 rid;

	spin_lock(&relay->lock);
	rid = ++relay->last_rid;
	spin_unlock(&relay->lock);

	return rid;
}

/**
 * struct relay_transaction - internal data used to handle transactions
 *
 * Relation between struct relay_transaction members::
 *
 *                 <-------------------- GUC_CTB_MAX_DWORDS -------------->
 *                                  <-------- GUC_RELAY_MSG_MAX_LEN --->
 *                 <--- offset ---> <--- request_len ------->
 *                +----------------+-------------------------+----------+--+
 *                |                |                         |          |  |
 *                +----------------+-------------------------+----------+--+
 *                ^                ^
 *               /                /
 *    request_buf          request
 *
 *                 <-------------------- GUC_CTB_MAX_DWORDS -------------->
 *                                  <-------- GUC_RELAY_MSG_MAX_LEN --->
 *                 <--- offset ---> <--- response_len --->
 *                +----------------+----------------------+-------------+--+
 *                |                |                      |             |  |
 *                +----------------+----------------------+-------------+--+
 *                ^                ^
 *               /                /
 *   response_buf         response
 */
struct relay_transaction {
	/**
	 * @incoming: indicates whether this transaction represents an incoming
	 *            request from the remote VF/PF or this transaction
	 *            represents outgoing request to the remote VF/PF.
	 */
	bool incoming;

	/**
	 * @remote: PF/VF identifier of the origin (or target) of the relay
	 *          request message.
	 */
	u32 remote;

	/** @rid: identifier of the VF/PF relay message. */
	u32 rid;

	/**
	 * @request: points to the inner VF/PF request message, copied to the
	 *           #response_buf starting at #offset.
	 */
	u32 *request;

	/** @request_len: length of the inner VF/PF request message. */
	u32 request_len;

	/**
	 * @response: points to the placeholder buffer where inner VF/PF
	 *            response will be located, for outgoing transaction
	 *            this could be caller's buffer (if provided) otherwise
	 *            it points to the #response_buf starting at #offset.
	 */
	u32 *response;

	/**
	 * @response_len: length of the inner VF/PF response message (only
	 *                if #status is 0), initially set to the size of the
	 *                placeholder buffer where response message will be
	 *                copied.
	 */
	u32 response_len;

	/**
	 * @offset: offset to the start of the inner VF/PF relay message inside
	 *          buffers; this offset is equal the length of the outer GuC
	 *          relay header message.
	 */
	u32 offset;

	/**
	 * @request_buf: buffer with VF/PF request message including outer
	 *               transport message.
	 */
	u32 request_buf[GUC_CTB_MAX_DWORDS];

	/**
	 * @response_buf: buffer with VF/PF response message including outer
	 *                transport message.
	 */
	u32 response_buf[GUC_CTB_MAX_DWORDS];

	/**
	 * @reply: status of the reply, 0 means that data pointed by the
	 *         #response is valid.
	 */
	int reply;

	/** @done: completion of the outgoing transaction. */
	struct completion done;

	/** @link: transaction list link */
	struct list_head link;
};

static u32 prepare_pf2guc(u32 *msg, u32 target, u32 rid)
{
	msg[0] = FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
		 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
		 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, XE_GUC_ACTION_PF2GUC_RELAY_TO_VF);
	msg[1] = FIELD_PREP(PF2GUC_RELAY_TO_VF_REQUEST_MSG_1_VFID, target);
	msg[2] = FIELD_PREP(PF2GUC_RELAY_TO_VF_REQUEST_MSG_2_RELAY_ID, rid);

	return PF2GUC_RELAY_TO_VF_REQUEST_MSG_MIN_LEN;
}

static u32 prepare_vf2guc(u32 *msg, u32 rid)
{
	msg[0] = FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
		 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
		 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, XE_GUC_ACTION_VF2GUC_RELAY_TO_PF);
	msg[1] = FIELD_PREP(VF2GUC_RELAY_TO_PF_REQUEST_MSG_1_RELAY_ID, rid);

	return VF2GUC_RELAY_TO_PF_REQUEST_MSG_MIN_LEN;
}

static struct relay_transaction *
__relay_get_transaction(struct xe_guc_relay *relay, bool incoming, u32 remote, u32 rid,
			const u32 *action, u32 action_len, u32 *resp, u32 resp_size)
{
	struct relay_transaction *txn;

	relay_assert(relay, action_len >= GUC_RELAY_MSG_MIN_LEN);
	relay_assert(relay, action_len <= GUC_RELAY_MSG_MAX_LEN);
	relay_assert(relay, !(!!resp ^ !!resp_size));
	relay_assert(relay, resp_size <= GUC_RELAY_MSG_MAX_LEN);
	relay_assert(relay, resp_size == 0 || resp_size >= GUC_RELAY_MSG_MIN_LEN);

	if (unlikely(!relay_is_ready(relay)))
		return ERR_PTR(-ENODEV);

	/*
	 * For incoming requests we can't use GFP_KERNEL as those are delivered
	 * with CTB lock held which is marked as used in the reclaim path.
	 * Btw, that's one of the reason why we use mempool here!
	 */
	txn = mempool_alloc(&relay->pool, incoming ? GFP_ATOMIC : GFP_KERNEL);
	if (!txn)
		return ERR_PTR(-ENOMEM);

	txn->incoming = incoming;
	txn->remote = remote;
	txn->rid = rid;
	txn->offset = remote ?
		prepare_pf2guc(incoming ? txn->response_buf : txn->request_buf, remote, rid) :
		prepare_vf2guc(incoming ? txn->response_buf : txn->request_buf, rid);

	relay_assert(relay, txn->offset);
	relay_assert(relay, txn->offset + GUC_RELAY_MSG_MAX_LEN <= ARRAY_SIZE(txn->request_buf));
	relay_assert(relay, txn->offset + GUC_RELAY_MSG_MAX_LEN <= ARRAY_SIZE(txn->response_buf));

	txn->request = txn->request_buf + txn->offset;
	memcpy(&txn->request_buf[txn->offset], action, sizeof(u32) * action_len);
	txn->request_len = action_len;

	txn->response = resp ?: txn->response_buf + txn->offset;
	txn->response_len = resp_size ?: GUC_RELAY_MSG_MAX_LEN;
	txn->reply = -ENOMSG;
	INIT_LIST_HEAD(&txn->link);
	init_completion(&txn->done);

	return txn;
}

static struct relay_transaction *
relay_new_transaction(struct xe_guc_relay *relay, u32 target, const u32 *action, u32 len,
		      u32 *resp, u32 resp_size)
{
	u32 rid = relay_get_next_rid(relay);

	return __relay_get_transaction(relay, false, target, rid, action, len, resp, resp_size);
}

static struct relay_transaction *
relay_new_incoming_transaction(struct xe_guc_relay *relay, u32 origin, u32 rid,
			       const u32 *action, u32 len)
{
	return __relay_get_transaction(relay, true, origin, rid, action, len, NULL, 0);
}

static void relay_release_transaction(struct xe_guc_relay *relay, struct relay_transaction *txn)
{
	relay_assert(relay, list_empty(&txn->link));

	txn->offset = 0;
	txn->response = NULL;
	txn->reply = -ESTALE;
	mempool_free(txn, &relay->pool);
}

static int relay_send_transaction(struct xe_guc_relay *relay, struct relay_transaction *txn)
{
	u32 len = txn->incoming ? txn->response_len : txn->request_len;
	u32 *buf = txn->incoming ? txn->response_buf : txn->request_buf;
	u32 *msg = buf + txn->offset;
	int ret;

	relay_assert(relay, txn->offset);
	relay_assert(relay, txn->offset + len <= GUC_CTB_MAX_DWORDS);
	relay_assert(relay, len >= GUC_RELAY_MSG_MIN_LEN);
	relay_assert(relay, len <= GUC_RELAY_MSG_MAX_LEN);

	relay_debug(relay, "sending %s.%u to %u = %*ph\n",
		    guc_hxg_type_to_string(FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0])),
		    txn->rid, txn->remote, (int)sizeof(u32) * len, msg);

	ret = xe_guc_ct_send_block(relay_to_ct(relay), buf, len + txn->offset);

	if (unlikely(ret > 0)) {
		relay_notice(relay, "Unexpected data=%d from GuC, wrong ABI?\n", ret);
		ret = -EPROTO;
	}
	if (unlikely(ret < 0)) {
		relay_notice(relay, "Failed to send %s.%x to GuC (%pe) %*ph ...\n",
			     guc_hxg_type_to_string(FIELD_GET(GUC_HXG_MSG_0_TYPE, buf[0])),
			     FIELD_GET(GUC_HXG_REQUEST_MSG_0_ACTION, buf[0]),
			     ERR_PTR(ret), (int)sizeof(u32) * txn->offset, buf);
		relay_notice(relay, "Failed to send %s.%u to %u (%pe) %*ph\n",
			     guc_hxg_type_to_string(FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0])),
			     txn->rid, txn->remote, ERR_PTR(ret), (int)sizeof(u32) * len, msg);
	}

	return ret;
}

static void __fini_relay(struct drm_device *drm, void *arg)
{
	struct xe_guc_relay *relay = arg;

	mempool_exit(&relay->pool);
}

/**
 * xe_guc_relay_init - Initialize a &xe_guc_relay
 * @relay: the &xe_guc_relay to initialize
 *
 * Initialize remaining members of &xe_guc_relay that may depend
 * on the SR-IOV mode.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int xe_guc_relay_init(struct xe_guc_relay *relay)
{
	const int XE_RELAY_MEMPOOL_MIN_NUM = 1;
	struct xe_device *xe = relay_to_xe(relay);
	int err;

	relay_assert(relay, !relay_is_ready(relay));

	if (!IS_SRIOV(xe))
		return 0;

	spin_lock_init(&relay->lock);
	INIT_WORK(&relay->worker, relays_worker_fn);
	INIT_LIST_HEAD(&relay->pending_relays);
	INIT_LIST_HEAD(&relay->incoming_actions);

	err = mempool_init_kmalloc_pool(&relay->pool, XE_RELAY_MEMPOOL_MIN_NUM +
					relay_get_totalvfs(relay),
					sizeof(struct relay_transaction));
	if (err)
		return err;

	relay_debug(relay, "using mempool with %d elements\n", relay->pool.min_nr);

	return drmm_add_action_or_reset(&xe->drm, __fini_relay, relay);
}

static u32 to_relay_error(int err)
{
	/* XXX: assume that relay errors match errno codes */
	return err < 0 ? -err : GUC_RELAY_ERROR_UNDISCLOSED;
}

static int from_relay_error(u32 error)
{
	/* XXX: assume that relay errors match errno codes */
	return error ? -error : -ENODATA;
}

static u32 sanitize_relay_error(u32 error)
{
	/* XXX TBD if generic error codes will be allowed */
	if (!IS_ENABLED(CONFIG_DRM_XE_DEBUG))
		error = GUC_RELAY_ERROR_UNDISCLOSED;
	return error;
}

static u32 sanitize_relay_error_hint(u32 hint)
{
	/* XXX TBD if generic error codes will be allowed */
	if (!IS_ENABLED(CONFIG_DRM_XE_DEBUG))
		hint = 0;
	return hint;
}

static u32 prepare_error_reply(u32 *msg, u32 error, u32 hint)
{
	msg[0] = FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
		 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_RESPONSE_FAILURE) |
		 FIELD_PREP(GUC_HXG_FAILURE_MSG_0_HINT, hint) |
		 FIELD_PREP(GUC_HXG_FAILURE_MSG_0_ERROR, error);

	XE_WARN_ON(!FIELD_FIT(GUC_HXG_FAILURE_MSG_0_ERROR, error));
	XE_WARN_ON(!FIELD_FIT(GUC_HXG_FAILURE_MSG_0_HINT, hint));

	return GUC_HXG_FAILURE_MSG_LEN;
}

static void relay_testonly_nop(struct xe_guc_relay *relay)
{
	KUNIT_STATIC_STUB_REDIRECT(relay_testonly_nop, relay);
}

static int relay_send_message_and_wait(struct xe_guc_relay *relay,
				       struct relay_transaction *txn,
				       u32 *buf, u32 buf_size)
{
	unsigned long timeout = msecs_to_jiffies(RELAY_TIMEOUT_MSEC);
	u32 *msg = &txn->request_buf[txn->offset];
	u32 len = txn->request_len;
	u32 type, action, data0;
	int ret;
	long n;

	type = FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0]);
	action = FIELD_GET(GUC_HXG_REQUEST_MSG_0_ACTION, msg[0]);
	data0 = FIELD_GET(GUC_HXG_REQUEST_MSG_0_DATA0, msg[0]);

	relay_debug(relay, "%s.%u to %u action %#x:%u\n",
		    guc_hxg_type_to_string(type),
		    txn->rid, txn->remote, action, data0);

	/* list ordering does not need to match RID ordering */
	spin_lock(&relay->lock);
	list_add_tail(&txn->link, &relay->pending_relays);
	spin_unlock(&relay->lock);

resend:
	ret = relay_send_transaction(relay, txn);
	if (unlikely(ret < 0))
		goto unlink;

wait:
	n = wait_for_completion_timeout(&txn->done, timeout);
	if (unlikely(n == 0 && txn->reply)) {
		ret = -ETIME;
		goto unlink;
	}

	relay_debug(relay, "%u.%u reply %d after %u msec\n",
		    txn->remote, txn->rid, txn->reply, jiffies_to_msecs(timeout - n));
	if (unlikely(txn->reply)) {
		reinit_completion(&txn->done);
		if (txn->reply == -EAGAIN)
			goto resend;
		if (txn->reply == -EBUSY) {
			relay_testonly_nop(relay);
			goto wait;
		}
		if (txn->reply > 0)
			ret = from_relay_error(txn->reply);
		else
			ret = txn->reply;
		goto unlink;
	}

	relay_debug(relay, "%u.%u response %*ph\n", txn->remote, txn->rid,
		    (int)sizeof(u32) * txn->response_len, txn->response);
	relay_assert(relay, txn->response_len >= GUC_RELAY_MSG_MIN_LEN);
	ret = txn->response_len;

unlink:
	spin_lock(&relay->lock);
	list_del_init(&txn->link);
	spin_unlock(&relay->lock);

	if (unlikely(ret < 0)) {
		relay_notice(relay, "Unsuccessful %s.%u %#x:%u to %u (%pe) %*ph\n",
			     guc_hxg_type_to_string(type), txn->rid,
			     action, data0, txn->remote, ERR_PTR(ret),
			     (int)sizeof(u32) * len, msg);
	}

	return ret;
}

static int relay_send_to(struct xe_guc_relay *relay, u32 target,
			 const u32 *msg, u32 len, u32 *buf, u32 buf_size)
{
	struct relay_transaction *txn;
	int ret;

	relay_assert(relay, len >= GUC_RELAY_MSG_MIN_LEN);
	relay_assert(relay, len <= GUC_RELAY_MSG_MAX_LEN);
	relay_assert(relay, FIELD_GET(GUC_HXG_MSG_0_ORIGIN, msg[0]) == GUC_HXG_ORIGIN_HOST);
	relay_assert(relay, guc_hxg_type_is_action(FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0])));

	if (unlikely(!relay_is_ready(relay)))
		return -ENODEV;

	txn = relay_new_transaction(relay, target, msg, len, buf, buf_size);
	if (IS_ERR(txn))
		return PTR_ERR(txn);

	switch (FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0])) {
	case GUC_HXG_TYPE_REQUEST:
		ret = relay_send_message_and_wait(relay, txn, buf, buf_size);
		break;
	case GUC_HXG_TYPE_FAST_REQUEST:
		relay_assert(relay, !GUC_HXG_TYPE_FAST_REQUEST);
		fallthrough;
	case GUC_HXG_TYPE_EVENT:
		ret = relay_send_transaction(relay, txn);
		break;
	default:
		ret = -EINVAL;
		break;
	}

	relay_release_transaction(relay, txn);
	return ret;
}

#ifdef CONFIG_PCI_IOV
/**
 * xe_guc_relay_send_to_vf - Send a message to the VF.
 * @relay: the &xe_guc_relay which will send the message
 * @target: target VF number
 * @msg: request message to be sent
 * @len: length of the request message (in dwords, can't be 0)
 * @buf: placeholder for the response message
 * @buf_size: size of the response message placeholder (in dwords)
 *
 * This function can only be used by the driver running in the SR-IOV PF mode.
 *
 * Return: Non-negative response length (in dwords) or
 *         a negative error code on failure.
 */
int xe_guc_relay_send_to_vf(struct xe_guc_relay *relay, u32 target,
			    const u32 *msg, u32 len, u32 *buf, u32 buf_size)
{
	relay_assert(relay, IS_SRIOV_PF(relay_to_xe(relay)));

	return relay_send_to(relay, target, msg, len, buf, buf_size);
}
#endif

/**
 * xe_guc_relay_send_to_pf - Send a message to the PF.
 * @relay: the &xe_guc_relay which will send the message
 * @msg: request message to be sent
 * @len: length of the message (in dwords, can't be 0)
 * @buf: placeholder for the response message
 * @buf_size: size of the response message placeholder (in dwords)
 *
 * This function can only be used by driver running in SR-IOV VF mode.
 *
 * Return: Non-negative response length (in dwords) or
 *         a negative error code on failure.
 */
int xe_guc_relay_send_to_pf(struct xe_guc_relay *relay,
			    const u32 *msg, u32 len, u32 *buf, u32 buf_size)
{
	relay_assert(relay, IS_SRIOV_VF(relay_to_xe(relay)));

	return relay_send_to(relay, PFID, msg, len, buf, buf_size);
}

static int relay_handle_reply(struct xe_guc_relay *relay, u32 origin,
			      u32 rid, int reply, const u32 *msg, u32 len)
{
	struct relay_transaction *pending;
	int err = -ESRCH;

	spin_lock(&relay->lock);
	list_for_each_entry(pending, &relay->pending_relays, link) {
		if (pending->remote != origin || pending->rid != rid) {
			relay_debug(relay, "%u.%u still awaits response\n",
				    pending->remote, pending->rid);
			continue;
		}
		err = 0; /* found! */
		if (reply == 0) {
			if (len > pending->response_len) {
				reply = -ENOBUFS;
				err = -ENOBUFS;
			} else {
				memcpy(pending->response, msg, 4 * len);
				pending->response_len = len;
			}
		}
		pending->reply = reply;
		complete_all(&pending->done);
		break;
	}
	spin_unlock(&relay->lock);

	return err;
}

static int relay_handle_failure(struct xe_guc_relay *relay, u32 origin,
				u32 rid, const u32 *msg, u32 len)
{
	int error = FIELD_GET(GUC_HXG_FAILURE_MSG_0_ERROR, msg[0]);
	u32 hint __maybe_unused = FIELD_GET(GUC_HXG_FAILURE_MSG_0_HINT, msg[0]);

	relay_assert(relay, len);
	relay_debug(relay, "%u.%u error %#x (%pe) hint %u debug %*ph\n",
		    origin, rid, error, ERR_PTR(-error), hint, 4 * (len - 1), msg + 1);

	return relay_handle_reply(relay, origin, rid, error ?: -EREMOTEIO, NULL, 0);
}

static int relay_testloop_action_handler(struct xe_guc_relay *relay, u32 origin,
					 const u32 *msg, u32 len, u32 *response, u32 size)
{
	static ktime_t last_reply = 0;
	u32 type = FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0]);
	u32 action = FIELD_GET(GUC_HXG_REQUEST_MSG_0_ACTION, msg[0]);
	u32 opcode = FIELD_GET(GUC_HXG_REQUEST_MSG_0_DATA0, msg[0]);
	ktime_t now = ktime_get();
	bool busy;
	int ret;

	relay_assert(relay, guc_hxg_type_is_action(type));
	relay_assert(relay, action == GUC_RELAY_ACTION_VFXPF_TESTLOOP);

	if (!IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV))
		return -ECONNREFUSED;

	if (!last_reply)
		last_reply = now;
	busy = ktime_before(now, ktime_add_ms(last_reply, 2 * RELAY_TIMEOUT_MSEC));
	if (!busy)
		last_reply = now;

	switch (opcode) {
	case VFXPF_TESTLOOP_OPCODE_NOP:
		if (type == GUC_HXG_TYPE_EVENT)
			return 0;
		return guc_hxg_msg_encode_success(response, 0);
	case VFXPF_TESTLOOP_OPCODE_BUSY:
		if (type == GUC_HXG_TYPE_EVENT)
			return -EPROTO;
		msleep(RELAY_TIMEOUT_MSEC / 8);
		if (busy)
			return -EINPROGRESS;
		return guc_hxg_msg_encode_success(response, 0);
	case VFXPF_TESTLOOP_OPCODE_RETRY:
		if (type == GUC_HXG_TYPE_EVENT)
			return -EPROTO;
		msleep(RELAY_TIMEOUT_MSEC / 8);
		if (busy)
			return guc_hxg_msg_encode_retry(response, 0);
		return guc_hxg_msg_encode_success(response, 0);
	case VFXPF_TESTLOOP_OPCODE_ECHO:
		if (type == GUC_HXG_TYPE_EVENT)
			return -EPROTO;
		if (size < len)
			return -ENOBUFS;
		ret = guc_hxg_msg_encode_success(response, len);
		memcpy(response + ret, msg + ret, (len - ret) * sizeof(u32));
		return len;
	case VFXPF_TESTLOOP_OPCODE_FAIL:
		return -EHWPOISON;
	default:
		break;
	}

	relay_notice(relay, "Unexpected action %#x opcode %#x\n", action, opcode);
	return -EBADRQC;
}

static int relay_action_handler(struct xe_guc_relay *relay, u32 origin,
				const u32 *msg, u32 len, u32 *response, u32 size)
{
	u32 type;
	int ret;

	relay_assert(relay, len >= GUC_HXG_MSG_MIN_LEN);

	if (FIELD_GET(GUC_HXG_REQUEST_MSG_0_ACTION, msg[0]) == GUC_RELAY_ACTION_VFXPF_TESTLOOP)
		return relay_testloop_action_handler(relay, origin, msg, len, response, size);

	type = FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0]);

	/* XXX: PF services will be added later */
	ret = -EOPNOTSUPP;

	if (type == GUC_HXG_TYPE_EVENT)
		relay_assert(relay, ret <= 0);

	return ret;
}

static struct relay_transaction *relay_dequeue_transaction(struct xe_guc_relay *relay)
{
	struct relay_transaction *txn;

	spin_lock(&relay->lock);
	txn = list_first_entry_or_null(&relay->incoming_actions, struct relay_transaction, link);
	if (txn)
		list_del_init(&txn->link);
	spin_unlock(&relay->lock);

	return txn;
}

static void relay_process_incoming_action(struct xe_guc_relay *relay)
{
	struct relay_transaction *txn;
	bool again = false;
	u32 type;
	int ret;

	txn = relay_dequeue_transaction(relay);
	if (!txn)
		return;

	type = FIELD_GET(GUC_HXG_MSG_0_TYPE, txn->request_buf[txn->offset]);

	ret = relay_action_handler(relay, txn->remote,
				   txn->request_buf + txn->offset, txn->request_len,
				   txn->response_buf + txn->offset,
				   ARRAY_SIZE(txn->response_buf) - txn->offset);

	if (ret == -EINPROGRESS) {
		again = true;
		ret = guc_hxg_msg_encode_busy(txn->response_buf + txn->offset, 0);
	}

	if (ret > 0) {
		txn->response_len = ret;
		ret = relay_send_transaction(relay, txn);
	}

	if (ret < 0) {
		u32 error = to_relay_error(ret);

		relay_notice(relay, "Failed to handle %s.%u from %u (%pe) %*ph\n",
			     guc_hxg_type_to_string(type), txn->rid, txn->remote,
			     ERR_PTR(ret), 4 * txn->request_len, txn->request_buf + txn->offset);

		txn->response_len = prepare_error_reply(txn->response_buf + txn->offset,
							txn->remote ?
							sanitize_relay_error(error) : error,
							txn->remote ?
							sanitize_relay_error_hint(-ret) : -ret);
		ret = relay_send_transaction(relay, txn);
		again = false;
	}

	if (again) {
		spin_lock(&relay->lock);
		list_add(&txn->link, &relay->incoming_actions);
		spin_unlock(&relay->lock);
		return;
	}

	if (unlikely(ret < 0))
		relay_notice(relay, "Failed to process action.%u (%pe) %*ph\n",
			     txn->rid, ERR_PTR(ret), 4 * txn->request_len,
			     txn->request_buf + txn->offset);

	relay_release_transaction(relay, txn);
}

static bool relay_needs_worker(struct xe_guc_relay *relay)
{
	return !list_empty(&relay->incoming_actions);
}

static void relay_kick_worker(struct xe_guc_relay *relay)
{
	KUNIT_STATIC_STUB_REDIRECT(relay_kick_worker, relay);
	queue_work(relay_to_xe(relay)->sriov.wq, &relay->worker);
}

static void relays_worker_fn(struct work_struct *w)
{
	struct xe_guc_relay *relay = container_of(w, struct xe_guc_relay, worker);

	relay_process_incoming_action(relay);

	if (relay_needs_worker(relay))
		relay_kick_worker(relay);
}

static int relay_queue_action_msg(struct xe_guc_relay *relay, u32 origin, u32 rid,
				  const u32 *msg, u32 len)
{
	struct relay_transaction *txn;

	txn = relay_new_incoming_transaction(relay, origin, rid, msg, len);
	if (IS_ERR(txn))
		return PTR_ERR(txn);

	spin_lock(&relay->lock);
	list_add_tail(&txn->link, &relay->incoming_actions);
	spin_unlock(&relay->lock);

	relay_kick_worker(relay);
	return 0;
}

static int relay_process_msg(struct xe_guc_relay *relay, u32 origin, u32 rid,
			     const u32 *msg, u32 len)
{
	u32 type;
	int err;

	if (unlikely(len < GUC_HXG_MSG_MIN_LEN))
		return -EPROTO;

	if (FIELD_GET(GUC_HXG_MSG_0_ORIGIN, msg[0]) != GUC_HXG_ORIGIN_HOST)
		return -EPROTO;

	type = FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0]);
	relay_debug(relay, "received %s.%u from %u = %*ph\n",
		    guc_hxg_type_to_string(type), rid, origin, 4 * len, msg);

	switch (type) {
	case GUC_HXG_TYPE_REQUEST:
	case GUC_HXG_TYPE_FAST_REQUEST:
	case GUC_HXG_TYPE_EVENT:
		err = relay_queue_action_msg(relay, origin, rid, msg, len);
		break;
	case GUC_HXG_TYPE_RESPONSE_SUCCESS:
		err = relay_handle_reply(relay, origin, rid, 0, msg, len);
		break;
	case GUC_HXG_TYPE_NO_RESPONSE_BUSY:
		err = relay_handle_reply(relay, origin, rid, -EBUSY, NULL, 0);
		break;
	case GUC_HXG_TYPE_NO_RESPONSE_RETRY:
		err = relay_handle_reply(relay, origin, rid, -EAGAIN, NULL, 0);
		break;
	case GUC_HXG_TYPE_RESPONSE_FAILURE:
		err = relay_handle_failure(relay, origin, rid, msg, len);
		break;
	default:
		err = -EBADRQC;
	}

	if (unlikely(err))
		relay_notice(relay, "Failed to process %s.%u from %u (%pe) %*ph\n",
			     guc_hxg_type_to_string(type), rid, origin,
			     ERR_PTR(err), 4 * len, msg);

	return err;
}

/**
 * xe_guc_relay_process_guc2vf - Handle relay notification message from the GuC.
 * @relay: the &xe_guc_relay which will handle the message
 * @msg: message to be handled
 * @len: length of the message (in dwords)
 *
 * This function will handle relay messages received from the GuC.
 *
 * This function is can only be used if driver is running in SR-IOV mode.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int xe_guc_relay_process_guc2vf(struct xe_guc_relay *relay, const u32 *msg, u32 len)
{
	u32 rid;

	relay_assert(relay, len >= GUC_HXG_MSG_MIN_LEN);
	relay_assert(relay, FIELD_GET(GUC_HXG_MSG_0_ORIGIN, msg[0]) == GUC_HXG_ORIGIN_GUC);
	relay_assert(relay, FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0]) == GUC_HXG_TYPE_EVENT);
	relay_assert(relay, FIELD_GET(GUC_HXG_EVENT_MSG_0_ACTION, msg[0]) ==
		     XE_GUC_ACTION_GUC2VF_RELAY_FROM_PF);

	if (unlikely(!IS_SRIOV_VF(relay_to_xe(relay)) && !kunit_get_current_test()))
		return -EPERM;

	if (unlikely(!relay_is_ready(relay)))
		return -ENODEV;

	if (unlikely(len < GUC2VF_RELAY_FROM_PF_EVENT_MSG_MIN_LEN))
		return -EPROTO;

	if (unlikely(len > GUC2VF_RELAY_FROM_PF_EVENT_MSG_MAX_LEN))
		return -EMSGSIZE;

	if (unlikely(FIELD_GET(GUC_HXG_EVENT_MSG_0_DATA0, msg[0])))
		return -EPFNOSUPPORT;

	rid = FIELD_GET(GUC2VF_RELAY_FROM_PF_EVENT_MSG_1_RELAY_ID, msg[1]);

	return relay_process_msg(relay, PFID, rid,
				 msg + GUC2VF_RELAY_FROM_PF_EVENT_MSG_MIN_LEN,
				 len - GUC2VF_RELAY_FROM_PF_EVENT_MSG_MIN_LEN);
}

#ifdef CONFIG_PCI_IOV
/**
 * xe_guc_relay_process_guc2pf - Handle relay notification message from the GuC.
 * @relay: the &xe_guc_relay which will handle the message
 * @msg: message to be handled
 * @len: length of the message (in dwords)
 *
 * This function will handle relay messages received from the GuC.
 *
 * This function can only be used if driver is running in SR-IOV PF mode.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int xe_guc_relay_process_guc2pf(struct xe_guc_relay *relay, const u32 *msg, u32 len)
{
	u32 origin, rid;
	int err;

	relay_assert(relay, len >= GUC_HXG_EVENT_MSG_MIN_LEN);
	relay_assert(relay, FIELD_GET(GUC_HXG_MSG_0_ORIGIN, msg[0]) == GUC_HXG_ORIGIN_GUC);
	relay_assert(relay, FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0]) == GUC_HXG_TYPE_EVENT);
	relay_assert(relay, FIELD_GET(GUC_HXG_EVENT_MSG_0_ACTION, msg[0]) ==
		     XE_GUC_ACTION_GUC2PF_RELAY_FROM_VF);

	if (unlikely(!IS_SRIOV_PF(relay_to_xe(relay)) && !kunit_get_current_test()))
		return -EPERM;

	if (unlikely(!relay_is_ready(relay)))
		return -ENODEV;

	if (unlikely(len < GUC2PF_RELAY_FROM_VF_EVENT_MSG_MIN_LEN))
		return -EPROTO;

	if (unlikely(len > GUC2PF_RELAY_FROM_VF_EVENT_MSG_MAX_LEN))
		return -EMSGSIZE;

	if (unlikely(FIELD_GET(GUC_HXG_EVENT_MSG_0_DATA0, msg[0])))
		return -EPFNOSUPPORT;

	origin = FIELD_GET(GUC2PF_RELAY_FROM_VF_EVENT_MSG_1_VFID, msg[1]);
	rid = FIELD_GET(GUC2PF_RELAY_FROM_VF_EVENT_MSG_2_RELAY_ID, msg[2]);

	if (unlikely(origin > relay_get_totalvfs(relay)))
		return -ENOENT;

	err = relay_process_msg(relay, origin, rid,
				msg + GUC2PF_RELAY_FROM_VF_EVENT_MSG_MIN_LEN,
				len - GUC2PF_RELAY_FROM_VF_EVENT_MSG_MIN_LEN);

	return err;
}
#endif

#if IS_BUILTIN(CONFIG_DRM_XE_KUNIT_TEST)
#include "tests/xe_guc_relay_test.c"
#endif
