// SPDX-License-Identifier: GPL-2.0
/*
 * Management-Controller-to-Driver Interface
 *
 * Copyright 2008-2013 Solarflare Communications Inc.
 * Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
 */
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/rwsem.h>
#include <linux/vmalloc.h>
#include <net/netevent.h>
#include <linux/log2.h>
#include <linux/net_tstamp.h>
#include <linux/wait.h>
#include <linux/cdx/bitfield.h>

#include <linux/cdx/mcdi.h>
#include "mcdid.h"

static void cdx_mcdi_cancel_cmd(struct cdx_mcdi *cdx, struct cdx_mcdi_cmd *cmd);
static void cdx_mcdi_wait_for_cleanup(struct cdx_mcdi *cdx);
static int cdx_mcdi_rpc_async_internal(struct cdx_mcdi *cdx,
				       struct cdx_mcdi_cmd *cmd,
				       unsigned int *handle);
static void cdx_mcdi_start_or_queue(struct cdx_mcdi_iface *mcdi,
				    bool allow_retry);
static void cdx_mcdi_cmd_start_or_queue(struct cdx_mcdi_iface *mcdi,
					struct cdx_mcdi_cmd *cmd);
static bool cdx_mcdi_complete_cmd(struct cdx_mcdi_iface *mcdi,
				  struct cdx_mcdi_cmd *cmd,
				  struct cdx_dword *outbuf,
				  int len,
				  struct list_head *cleanup_list);
static void cdx_mcdi_timeout_cmd(struct cdx_mcdi_iface *mcdi,
				 struct cdx_mcdi_cmd *cmd,
				 struct list_head *cleanup_list);
static void cdx_mcdi_cmd_work(struct work_struct *context);
static void cdx_mcdi_mode_fail(struct cdx_mcdi *cdx, struct list_head *cleanup_list);
static void _cdx_mcdi_display_error(struct cdx_mcdi *cdx, unsigned int cmd,
				    size_t inlen, int raw, int arg, int err_no);

static bool cdx_cmd_cancelled(struct cdx_mcdi_cmd *cmd)
{
	return cmd->state == MCDI_STATE_RUNNING_CANCELLED;
}

static void cdx_mcdi_cmd_release(struct kref *ref)
{
	kfree(container_of(ref, struct cdx_mcdi_cmd, ref));
}

static unsigned int cdx_mcdi_cmd_handle(struct cdx_mcdi_cmd *cmd)
{
	return cmd->handle;
}

static void _cdx_mcdi_remove_cmd(struct cdx_mcdi_iface *mcdi,
				 struct cdx_mcdi_cmd *cmd,
				 struct list_head *cleanup_list)
{
	/* if cancelled, the completers have already been called */
	if (cdx_cmd_cancelled(cmd))
		return;

	if (cmd->completer) {
		list_add_tail(&cmd->cleanup_list, cleanup_list);
		++mcdi->outstanding_cleanups;
		kref_get(&cmd->ref);
	}
}

static void cdx_mcdi_remove_cmd(struct cdx_mcdi_iface *mcdi,
				struct cdx_mcdi_cmd *cmd,
				struct list_head *cleanup_list)
{
	list_del(&cmd->list);
	_cdx_mcdi_remove_cmd(mcdi, cmd, cleanup_list);
	cmd->state = MCDI_STATE_FINISHED;
	kref_put(&cmd->ref, cdx_mcdi_cmd_release);
	if (list_empty(&mcdi->cmd_list))
		wake_up(&mcdi->cmd_complete_wq);
}

static unsigned long cdx_mcdi_rpc_timeout(struct cdx_mcdi *cdx, unsigned int cmd)
{
	if (!cdx->mcdi_ops->mcdi_rpc_timeout)
		return MCDI_RPC_TIMEOUT;
	else
		return cdx->mcdi_ops->mcdi_rpc_timeout(cdx, cmd);
}

/**
 * cdx_mcdi_init - Initialize MCDI (Management Controller Driver Interface) state
 * @cdx:	Handle to the CDX MCDI structure
 *
 * This function allocates and initializes internal MCDI structures and resources
 * for the CDX device, including the workqueue, locking primitives, and command
 * tracking mechanisms. It sets the initial operating mode and prepares the device
 * for MCDI operations.
 *
 * Return:
 * * 0        - on success
 * * -ENOMEM  - if memory allocation or workqueue creation fails
 */
int cdx_mcdi_init(struct cdx_mcdi *cdx)
{
	struct cdx_mcdi_iface *mcdi;
	int rc = -ENOMEM;

	cdx->mcdi = kzalloc_obj(*cdx->mcdi);
	if (!cdx->mcdi)
		goto fail;

	mcdi = cdx_mcdi_if(cdx);
	mcdi->cdx = cdx;

	mcdi->workqueue = alloc_ordered_workqueue("mcdi_wq", 0);
	if (!mcdi->workqueue)
		goto fail2;
	mutex_init(&mcdi->iface_lock);
	mcdi->mode = MCDI_MODE_EVENTS;
	INIT_LIST_HEAD(&mcdi->cmd_list);
	init_waitqueue_head(&mcdi->cmd_complete_wq);

	mcdi->new_epoch = true;

	return 0;
fail2:
	kfree(cdx->mcdi);
	cdx->mcdi = NULL;
fail:
	return rc;
}
EXPORT_SYMBOL_GPL(cdx_mcdi_init);

/**
 * cdx_mcdi_finish - Cleanup MCDI (Management Controller Driver Interface) state
 * @cdx:	Handle to the CDX MCDI structure
 *
 * This function is responsible for cleaning up the MCDI (Management Controller Driver Interface)
 * resources associated with a cdx_mcdi structure. Also destroys the mcdi workqueue.
 *
 */
void cdx_mcdi_finish(struct cdx_mcdi *cdx)
{
	struct cdx_mcdi_iface *mcdi;

	mcdi = cdx_mcdi_if(cdx);
	if (!mcdi)
		return;

	cdx_mcdi_wait_for_cleanup(cdx);

	destroy_workqueue(mcdi->workqueue);
	kfree(cdx->mcdi);
	cdx->mcdi = NULL;
}
EXPORT_SYMBOL_GPL(cdx_mcdi_finish);

static bool cdx_mcdi_flushed(struct cdx_mcdi_iface *mcdi, bool ignore_cleanups)
{
	bool flushed;

	mutex_lock(&mcdi->iface_lock);
	flushed = list_empty(&mcdi->cmd_list) &&
		  (ignore_cleanups || !mcdi->outstanding_cleanups);
	mutex_unlock(&mcdi->iface_lock);
	return flushed;
}

/* Wait for outstanding MCDI commands to complete. */
static void cdx_mcdi_wait_for_cleanup(struct cdx_mcdi *cdx)
{
	struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);

	if (!mcdi)
		return;

	wait_event(mcdi->cmd_complete_wq,
		   cdx_mcdi_flushed(mcdi, false));
}

int cdx_mcdi_wait_for_quiescence(struct cdx_mcdi *cdx,
				 unsigned int timeout_jiffies)
{
	struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
	DEFINE_WAIT_FUNC(wait, woken_wake_function);
	int rc = 0;

	if (!mcdi)
		return -EINVAL;

	flush_workqueue(mcdi->workqueue);

	add_wait_queue(&mcdi->cmd_complete_wq, &wait);

	while (!cdx_mcdi_flushed(mcdi, true)) {
		rc = wait_woken(&wait, TASK_IDLE, timeout_jiffies);
		if (rc)
			continue;
		break;
	}

	remove_wait_queue(&mcdi->cmd_complete_wq, &wait);

	if (rc > 0)
		rc = 0;
	else if (rc == 0)
		rc = -ETIMEDOUT;

	return rc;
}

static u8 cdx_mcdi_payload_csum(const struct cdx_dword *hdr, size_t hdr_len,
				const struct cdx_dword *sdu, size_t sdu_len)
{
	u8 *p = (u8 *)hdr;
	u8 csum = 0;
	int i;

	for (i = 0; i < hdr_len; i++)
		csum += p[i];

	p = (u8 *)sdu;
	for (i = 0; i < sdu_len; i++)
		csum += p[i];

	return ~csum & 0xff;
}

static void cdx_mcdi_send_request(struct cdx_mcdi *cdx,
				  struct cdx_mcdi_cmd *cmd)
{
	struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
	const struct cdx_dword *inbuf = cmd->inbuf;
	size_t inlen = cmd->inlen;
	struct cdx_dword hdr[2];
	size_t hdr_len;
	bool not_epoch;
	u32 xflags;

	if (!mcdi)
		return;

	mcdi->prev_seq = cmd->seq;
	mcdi->seq_held_by[cmd->seq] = cmd;
	mcdi->db_held_by = cmd;
	cmd->started = jiffies;

	not_epoch = !mcdi->new_epoch;
	xflags = 0;

	/* MCDI v2 */
	WARN_ON(inlen > MCDI_CTL_SDU_LEN_MAX_V2);
	CDX_POPULATE_DWORD_7(hdr[0],
			     MCDI_HEADER_RESPONSE, 0,
			     MCDI_HEADER_RESYNC, 1,
			     MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
			     MCDI_HEADER_DATALEN, 0,
			     MCDI_HEADER_SEQ, cmd->seq,
			     MCDI_HEADER_XFLAGS, xflags,
			     MCDI_HEADER_NOT_EPOCH, not_epoch);
	CDX_POPULATE_DWORD_3(hdr[1],
			     MC_CMD_V2_EXTN_IN_EXTENDED_CMD, cmd->cmd,
			     MC_CMD_V2_EXTN_IN_ACTUAL_LEN, inlen,
			     MC_CMD_V2_EXTN_IN_MESSAGE_TYPE,
			     MC_CMD_V2_EXTN_IN_MCDI_MESSAGE_TYPE_PLATFORM);
	hdr_len = 8;

	hdr[0].cdx_u32 |= (__force __le32)(cdx_mcdi_payload_csum(hdr, hdr_len, inbuf, inlen) <<
			 MCDI_HEADER_XFLAGS_LBN);

	print_hex_dump_debug("MCDI REQ HEADER: ", DUMP_PREFIX_NONE, 32, 4, hdr, hdr_len, false);
	print_hex_dump_debug("MCDI REQ PAYLOAD: ", DUMP_PREFIX_NONE, 32, 4, inbuf, inlen, false);

	cdx->mcdi_ops->mcdi_request(cdx, hdr, hdr_len, inbuf, inlen);

	mcdi->new_epoch = false;
}

static int cdx_mcdi_errno(struct cdx_mcdi *cdx, unsigned int mcdi_err)
{
	switch (mcdi_err) {
	case 0:
	case MC_CMD_ERR_QUEUE_FULL:
		return mcdi_err;
	case MC_CMD_ERR_EPERM:
		return -EPERM;
	case MC_CMD_ERR_ENOENT:
		return -ENOENT;
	case MC_CMD_ERR_EINTR:
		return -EINTR;
	case MC_CMD_ERR_EAGAIN:
		return -EAGAIN;
	case MC_CMD_ERR_EACCES:
		return -EACCES;
	case MC_CMD_ERR_EBUSY:
		return -EBUSY;
	case MC_CMD_ERR_EINVAL:
		return -EINVAL;
	case MC_CMD_ERR_ERANGE:
		return -ERANGE;
	case MC_CMD_ERR_EDEADLK:
		return -EDEADLK;
	case MC_CMD_ERR_ENOSYS:
		return -EOPNOTSUPP;
	case MC_CMD_ERR_ETIME:
		return -ETIME;
	case MC_CMD_ERR_EALREADY:
		return -EALREADY;
	case MC_CMD_ERR_ENOSPC:
		return -ENOSPC;
	case MC_CMD_ERR_ENOMEM:
		return -ENOMEM;
	case MC_CMD_ERR_ENOTSUP:
		return -EOPNOTSUPP;
	case MC_CMD_ERR_ALLOC_FAIL:
		return -ENOBUFS;
	case MC_CMD_ERR_MAC_EXIST:
		return -EADDRINUSE;
	case MC_CMD_ERR_NO_EVB_PORT:
		return -EAGAIN;
	default:
		return -EPROTO;
	}
}

static void cdx_mcdi_process_cleanup_list(struct cdx_mcdi *cdx,
					  struct list_head *cleanup_list)
{
	struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
	unsigned int cleanups = 0;

	if (!mcdi)
		return;

	while (!list_empty(cleanup_list)) {
		struct cdx_mcdi_cmd *cmd =
			list_first_entry(cleanup_list,
					 struct cdx_mcdi_cmd, cleanup_list);
		cmd->completer(cdx, cmd->cookie, cmd->rc,
			       cmd->outbuf, cmd->outlen);
		list_del(&cmd->cleanup_list);
		kref_put(&cmd->ref, cdx_mcdi_cmd_release);
		++cleanups;
	}

	if (cleanups) {
		bool all_done;

		mutex_lock(&mcdi->iface_lock);
		CDX_WARN_ON_PARANOID(cleanups > mcdi->outstanding_cleanups);
		all_done = (mcdi->outstanding_cleanups -= cleanups) == 0;
		mutex_unlock(&mcdi->iface_lock);
		if (all_done)
			wake_up(&mcdi->cmd_complete_wq);
	}
}

static void _cdx_mcdi_cancel_cmd(struct cdx_mcdi_iface *mcdi,
				 unsigned int handle,
				 struct list_head *cleanup_list)
{
	struct cdx_mcdi_cmd *cmd;

	list_for_each_entry(cmd, &mcdi->cmd_list, list)
		if (cdx_mcdi_cmd_handle(cmd) == handle) {
			switch (cmd->state) {
			case MCDI_STATE_QUEUED:
			case MCDI_STATE_RETRY:
				pr_debug("command %#x inlen %zu cancelled in queue\n",
					 cmd->cmd, cmd->inlen);
				/* if not yet running, properly cancel it */
				cmd->rc = -EPIPE;
				cdx_mcdi_remove_cmd(mcdi, cmd, cleanup_list);
				break;
			case MCDI_STATE_RUNNING:
			case MCDI_STATE_RUNNING_CANCELLED:
			case MCDI_STATE_FINISHED:
			default:
				/* invalid state? */
				WARN_ON(1);
			}
			break;
		}
}

static void cdx_mcdi_cancel_cmd(struct cdx_mcdi *cdx, struct cdx_mcdi_cmd *cmd)
{
	struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
	LIST_HEAD(cleanup_list);

	if (!mcdi)
		return;

	mutex_lock(&mcdi->iface_lock);
	cdx_mcdi_timeout_cmd(mcdi, cmd, &cleanup_list);
	mutex_unlock(&mcdi->iface_lock);
	cdx_mcdi_process_cleanup_list(cdx, &cleanup_list);
}

struct cdx_mcdi_blocking_data {
	struct kref ref;
	bool done;
	wait_queue_head_t wq;
	int rc;
	struct cdx_dword *outbuf;
	size_t outlen;
	size_t outlen_actual;
};

static void cdx_mcdi_blocking_data_release(struct kref *ref)
{
	kfree(container_of(ref, struct cdx_mcdi_blocking_data, ref));
}

static void cdx_mcdi_rpc_completer(struct cdx_mcdi *cdx, unsigned long cookie,
				   int rc, struct cdx_dword *outbuf,
				   size_t outlen_actual)
{
	struct cdx_mcdi_blocking_data *wait_data =
		(struct cdx_mcdi_blocking_data *)cookie;

	wait_data->rc = rc;
	memcpy(wait_data->outbuf, outbuf,
	       min(outlen_actual, wait_data->outlen));
	wait_data->outlen_actual = outlen_actual;
	/* memory barrier */
	smp_wmb();
	wait_data->done = true;
	wake_up(&wait_data->wq);
	kref_put(&wait_data->ref, cdx_mcdi_blocking_data_release);
}

static int cdx_mcdi_rpc_sync(struct cdx_mcdi *cdx, unsigned int cmd,
			     const struct cdx_dword *inbuf, size_t inlen,
			     struct cdx_dword *outbuf, size_t outlen,
			     size_t *outlen_actual, bool quiet)
{
	struct cdx_mcdi_blocking_data *wait_data;
	struct cdx_mcdi_cmd *cmd_item;
	unsigned int handle;
	int rc;

	if (outlen_actual)
		*outlen_actual = 0;

	wait_data = kmalloc_obj(*wait_data);
	if (!wait_data)
		return -ENOMEM;

	cmd_item = kmalloc_obj(*cmd_item);
	if (!cmd_item) {
		kfree(wait_data);
		return -ENOMEM;
	}

	kref_init(&wait_data->ref);
	wait_data->done = false;
	init_waitqueue_head(&wait_data->wq);
	wait_data->outbuf = outbuf;
	wait_data->outlen = outlen;

	kref_init(&cmd_item->ref);
	cmd_item->quiet = quiet;
	cmd_item->cookie = (unsigned long)wait_data;
	cmd_item->completer = &cdx_mcdi_rpc_completer;
	cmd_item->cmd = cmd;
	cmd_item->inlen = inlen;
	cmd_item->inbuf = inbuf;

	/* Claim an extra reference for the completer to put. */
	kref_get(&wait_data->ref);
	rc = cdx_mcdi_rpc_async_internal(cdx, cmd_item, &handle);
	if (rc) {
		kref_put(&wait_data->ref, cdx_mcdi_blocking_data_release);
		goto out;
	}

	if (!wait_event_timeout(wait_data->wq, wait_data->done,
				cdx_mcdi_rpc_timeout(cdx, cmd)) &&
	    !wait_data->done) {
		pr_err("MC command 0x%x inlen %zu timed out (sync)\n",
		       cmd, inlen);

		cdx_mcdi_cancel_cmd(cdx, cmd_item);

		wait_data->rc = -ETIMEDOUT;
		wait_data->outlen_actual = 0;
	}

	if (outlen_actual)
		*outlen_actual = wait_data->outlen_actual;
	rc = wait_data->rc;

out:
	kref_put(&wait_data->ref, cdx_mcdi_blocking_data_release);

	return rc;
}

static bool cdx_mcdi_get_seq(struct cdx_mcdi_iface *mcdi, unsigned char *seq)
{
	*seq = mcdi->prev_seq;
	do {
		*seq = (*seq + 1) % ARRAY_SIZE(mcdi->seq_held_by);
	} while (mcdi->seq_held_by[*seq] && *seq != mcdi->prev_seq);
	return !mcdi->seq_held_by[*seq];
}

static int cdx_mcdi_rpc_async_internal(struct cdx_mcdi *cdx,
				       struct cdx_mcdi_cmd *cmd,
				       unsigned int *handle)
{
	struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);
	LIST_HEAD(cleanup_list);

	if (!mcdi) {
		kref_put(&cmd->ref, cdx_mcdi_cmd_release);
		return -ENETDOWN;
	}

	if (mcdi->mode == MCDI_MODE_FAIL) {
		kref_put(&cmd->ref, cdx_mcdi_cmd_release);
		return -ENETDOWN;
	}

	cmd->mcdi = mcdi;
	INIT_WORK(&cmd->work, cdx_mcdi_cmd_work);
	INIT_LIST_HEAD(&cmd->list);
	INIT_LIST_HEAD(&cmd->cleanup_list);
	cmd->rc = 0;
	cmd->outbuf = NULL;
	cmd->outlen = 0;

	queue_work(mcdi->workqueue, &cmd->work);
	return 0;
}

static void cdx_mcdi_cmd_start_or_queue(struct cdx_mcdi_iface *mcdi,
					struct cdx_mcdi_cmd *cmd)
{
	struct cdx_mcdi *cdx = mcdi->cdx;
	u8 seq;

	if (!mcdi->db_held_by &&
	    cdx_mcdi_get_seq(mcdi, &seq)) {
		cmd->seq = seq;
		cmd->reboot_seen = false;
		cdx_mcdi_send_request(cdx, cmd);
		cmd->state = MCDI_STATE_RUNNING;
	} else {
		cmd->state = MCDI_STATE_QUEUED;
	}
}

/* try to advance other commands */
static void cdx_mcdi_start_or_queue(struct cdx_mcdi_iface *mcdi,
				    bool allow_retry)
{
	struct cdx_mcdi_cmd *cmd, *tmp;

	list_for_each_entry_safe(cmd, tmp, &mcdi->cmd_list, list)
		if (cmd->state == MCDI_STATE_QUEUED ||
		    (cmd->state == MCDI_STATE_RETRY && allow_retry))
			cdx_mcdi_cmd_start_or_queue(mcdi, cmd);
}

/**
 * cdx_mcdi_process_cmd - Process an incoming MCDI response
 * @cdx:	Handle to the CDX MCDI structure
 * @outbuf:	Pointer to the response buffer received from the management controller
 * @len:	Length of the response buffer in bytes
 *
 * This function handles a response from the management controller. It locates the
 * corresponding command using the sequence number embedded in the header,
 * completes the command if it is still pending, and initiates any necessary cleanup.
 *
 * The function assumes that the response buffer is well-formed and at least one
 * dword in size.
 */
void cdx_mcdi_process_cmd(struct cdx_mcdi *cdx, struct cdx_dword *outbuf, int len)
{
	struct cdx_mcdi_iface *mcdi;
	struct cdx_mcdi_cmd *cmd;
	LIST_HEAD(cleanup_list);
	unsigned int respseq;

	if (!len || !outbuf) {
		pr_err("Got empty MC response\n");
		return;
	}

	mcdi = cdx_mcdi_if(cdx);
	if (!mcdi)
		return;

	respseq = CDX_DWORD_FIELD(outbuf[0], MCDI_HEADER_SEQ);

	mutex_lock(&mcdi->iface_lock);
	cmd = mcdi->seq_held_by[respseq];

	if (cmd) {
		if (cmd->state == MCDI_STATE_FINISHED) {
			mutex_unlock(&mcdi->iface_lock);
			kref_put(&cmd->ref, cdx_mcdi_cmd_release);
			return;
		}

		cdx_mcdi_complete_cmd(mcdi, cmd, outbuf, len, &cleanup_list);
	} else {
		pr_err("MC response unexpected for seq : %0X\n", respseq);
	}

	mutex_unlock(&mcdi->iface_lock);

	cdx_mcdi_process_cleanup_list(mcdi->cdx, &cleanup_list);
}
EXPORT_SYMBOL_GPL(cdx_mcdi_process_cmd);

static void cdx_mcdi_cmd_work(struct work_struct *context)
{
	struct cdx_mcdi_cmd *cmd =
		container_of(context, struct cdx_mcdi_cmd, work);
	struct cdx_mcdi_iface *mcdi = cmd->mcdi;

	mutex_lock(&mcdi->iface_lock);

	cmd->handle = mcdi->prev_handle++;
	list_add_tail(&cmd->list, &mcdi->cmd_list);
	cdx_mcdi_cmd_start_or_queue(mcdi, cmd);

	mutex_unlock(&mcdi->iface_lock);
}

/*
 * Returns true if the MCDI module is finished with the command.
 * (examples of false would be if the command was proxied, or it was
 * rejected by the MC due to lack of resources and requeued).
 */
static bool cdx_mcdi_complete_cmd(struct cdx_mcdi_iface *mcdi,
				  struct cdx_mcdi_cmd *cmd,
				  struct cdx_dword *outbuf,
				  int len,
				  struct list_head *cleanup_list)
{
	size_t resp_hdr_len, resp_data_len;
	struct cdx_mcdi *cdx = mcdi->cdx;
	unsigned int respcmd, error;
	bool completed = false;
	int rc;

	/* ensure the command can't go away before this function returns */
	kref_get(&cmd->ref);

	respcmd = CDX_DWORD_FIELD(outbuf[0], MCDI_HEADER_CODE);
	error = CDX_DWORD_FIELD(outbuf[0], MCDI_HEADER_ERROR);

	if (respcmd != MC_CMD_V2_EXTN) {
		resp_hdr_len = 4;
		resp_data_len = CDX_DWORD_FIELD(outbuf[0], MCDI_HEADER_DATALEN);
	} else {
		resp_data_len = 0;
		resp_hdr_len = 8;
		if (len >= 8)
			resp_data_len =
				CDX_DWORD_FIELD(outbuf[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
	}

	if ((resp_hdr_len + resp_data_len) > len) {
		pr_warn("Incomplete MCDI response received %d. Expected %zu\n",
			len, (resp_hdr_len + resp_data_len));
		resp_data_len = 0;
	}

	print_hex_dump_debug("MCDI RESP HEADER: ", DUMP_PREFIX_NONE, 32, 4,
			     outbuf, resp_hdr_len, false);
	print_hex_dump_debug("MCDI RESP PAYLOAD: ", DUMP_PREFIX_NONE, 32, 4,
			     outbuf + (resp_hdr_len / 4), resp_data_len, false);

	if (error && resp_data_len == 0) {
		/* MC rebooted during command */
		rc = -EIO;
	} else {
		if (WARN_ON_ONCE(error && resp_data_len < 4))
			resp_data_len = 4;
		if (error) {
			rc = CDX_DWORD_FIELD(outbuf[resp_hdr_len / 4], CDX_DWORD);
			if (!cmd->quiet) {
				int err_arg = 0;

				if (resp_data_len >= MC_CMD_ERR_ARG_OFST + 4) {
					int offset = (resp_hdr_len + MC_CMD_ERR_ARG_OFST) / 4;

					err_arg = CDX_DWORD_VAL(outbuf[offset]);
				}

				_cdx_mcdi_display_error(cdx, cmd->cmd,
							cmd->inlen, rc, err_arg,
							cdx_mcdi_errno(cdx, rc));
			}
			rc = cdx_mcdi_errno(cdx, rc);
		} else {
			rc = 0;
		}
	}

	/* free doorbell */
	if (mcdi->db_held_by == cmd)
		mcdi->db_held_by = NULL;

	if (cdx_cmd_cancelled(cmd)) {
		list_del(&cmd->list);
		kref_put(&cmd->ref, cdx_mcdi_cmd_release);
		completed = true;
	} else if (rc == MC_CMD_ERR_QUEUE_FULL) {
		cmd->state = MCDI_STATE_RETRY;
	} else {
		cmd->rc = rc;
		cmd->outbuf = outbuf + DIV_ROUND_UP(resp_hdr_len, 4);
		cmd->outlen = resp_data_len;
		cdx_mcdi_remove_cmd(mcdi, cmd, cleanup_list);
		completed = true;
	}

	/* free sequence number and buffer */
	mcdi->seq_held_by[cmd->seq] = NULL;

	cdx_mcdi_start_or_queue(mcdi, rc != MC_CMD_ERR_QUEUE_FULL);

	/* wake up anyone waiting for flush */
	wake_up(&mcdi->cmd_complete_wq);

	kref_put(&cmd->ref, cdx_mcdi_cmd_release);

	return completed;
}

static void cdx_mcdi_timeout_cmd(struct cdx_mcdi_iface *mcdi,
				 struct cdx_mcdi_cmd *cmd,
				 struct list_head *cleanup_list)
{
	struct cdx_mcdi *cdx = mcdi->cdx;

	pr_err("MC command 0x%x inlen %zu state %d timed out after %u ms\n",
	       cmd->cmd, cmd->inlen, cmd->state,
	       jiffies_to_msecs(jiffies - cmd->started));

	cmd->rc = -ETIMEDOUT;
	cdx_mcdi_remove_cmd(mcdi, cmd, cleanup_list);

	cdx_mcdi_mode_fail(cdx, cleanup_list);
}

/**
 * cdx_mcdi_rpc - Issue an MCDI command and wait for completion
 * @cdx: NIC through which to issue the command
 * @cmd: Command type number
 * @inbuf: Command parameters
 * @inlen: Length of command parameters, in bytes. Must be a multiple
 *	of 4 and no greater than %MCDI_CTL_SDU_LEN_MAX_V1.
 * @outbuf: Response buffer. May be %NULL if @outlen is 0.
 * @outlen: Length of response buffer, in bytes. If the actual
 *	response is longer than @outlen & ~3, it will be truncated
 *	to that length.
 * @outlen_actual: Pointer through which to return the actual response
 *	length. May be %NULL if this is not needed.
 *
 * This function may sleep and therefore must be called in process
 * context.
 *
 * Return: A negative error code, or zero if successful. The error
 *	code may come from the MCDI response or may indicate a failure
 *	to communicate with the MC. In the former case, the response
 *	will still be copied to @outbuf and *@outlen_actual will be
 *	set accordingly. In the latter case, *@outlen_actual will be
 *	set to zero.
 */
int cdx_mcdi_rpc(struct cdx_mcdi *cdx, unsigned int cmd,
		 const struct cdx_dword *inbuf, size_t inlen,
		 struct cdx_dword *outbuf, size_t outlen,
		 size_t *outlen_actual)
{
	return cdx_mcdi_rpc_sync(cdx, cmd, inbuf, inlen, outbuf, outlen,
				 outlen_actual, false);
}
EXPORT_SYMBOL_GPL(cdx_mcdi_rpc);

/**
 * cdx_mcdi_rpc_async - Schedule an MCDI command to run asynchronously
 * @cdx: NIC through which to issue the command
 * @cmd: Command type number
 * @inbuf: Command parameters
 * @inlen: Length of command parameters, in bytes
 * @complete: Function to be called on completion or cancellation.
 * @cookie: Arbitrary value to be passed to @complete.
 *
 * This function does not sleep and therefore may be called in atomic
 * context.  It will fail if event queues are disabled or if MCDI
 * event completions have been disabled due to an error.
 *
 * If it succeeds, the @complete function will be called exactly once
 * in process context, when one of the following occurs:
 * (a) the completion event is received (in process context)
 * (b) event queues are disabled (in the process that disables them)
 */
int
cdx_mcdi_rpc_async(struct cdx_mcdi *cdx, unsigned int cmd,
		   const struct cdx_dword *inbuf, size_t inlen,
		   cdx_mcdi_async_completer *complete, unsigned long cookie)
{
	struct cdx_mcdi_cmd *cmd_item =
		kmalloc(sizeof(struct cdx_mcdi_cmd) + inlen, GFP_ATOMIC);

	if (!cmd_item)
		return -ENOMEM;

	kref_init(&cmd_item->ref);
	cmd_item->quiet = true;
	cmd_item->cookie = cookie;
	cmd_item->completer = complete;
	cmd_item->cmd = cmd;
	cmd_item->inlen = inlen;
	/* inbuf is probably not valid after return, so take a copy */
	cmd_item->inbuf = (struct cdx_dword *)(cmd_item + 1);
	memcpy(cmd_item + 1, inbuf, inlen);

	return cdx_mcdi_rpc_async_internal(cdx, cmd_item, NULL);
}

static void _cdx_mcdi_display_error(struct cdx_mcdi *cdx, unsigned int cmd,
				    size_t inlen, int raw, int arg, int err_no)
{
	pr_err("MC command 0x%x inlen %d failed err_no=%d (raw=%d) arg=%d\n",
	       cmd, (int)inlen, err_no, raw, arg);
}

/*
 * Set MCDI mode to fail to prevent any new commands, then cancel any
 * outstanding commands.
 * Caller must hold the mcdi iface_lock.
 */
static void cdx_mcdi_mode_fail(struct cdx_mcdi *cdx, struct list_head *cleanup_list)
{
	struct cdx_mcdi_iface *mcdi = cdx_mcdi_if(cdx);

	if (!mcdi)
		return;

	mcdi->mode = MCDI_MODE_FAIL;

	while (!list_empty(&mcdi->cmd_list)) {
		struct cdx_mcdi_cmd *cmd;

		cmd = list_first_entry(&mcdi->cmd_list, struct cdx_mcdi_cmd,
				       list);
		_cdx_mcdi_cancel_cmd(mcdi, cdx_mcdi_cmd_handle(cmd), cleanup_list);
	}
}
