// 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 "bitfield.h"
#include "mcdi.h"

struct cdx_mcdi_copy_buffer {
	struct cdx_dword buffer[DIV_ROUND_UP(MCDI_CTL_SDU_LEN_MAX, 4)];
};

#ifdef CONFIG_MCDI_LOGGING
#define LOG_LINE_MAX		(1024 - 32)
#endif

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);
}

int cdx_mcdi_init(struct cdx_mcdi *cdx)
{
	struct cdx_mcdi_iface *mcdi;
	int rc = -ENOMEM;

	cdx->mcdi = kzalloc(sizeof(*cdx->mcdi), GFP_KERNEL);
	if (!cdx->mcdi)
		goto fail;

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

#ifdef CONFIG_MCDI_LOGGING
	mcdi->logging_buffer = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
	if (!mcdi->logging_buffer)
		goto fail2;
#endif
	mcdi->workqueue = alloc_ordered_workqueue("mcdi_wq", 0);
	if (!mcdi->workqueue)
		goto fail3;
	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;
fail3:
#ifdef CONFIG_MCDI_LOGGING
	kfree(mcdi->logging_buffer);
fail2:
#endif
	kfree(cdx->mcdi);
	cdx->mcdi = NULL;
fail:
	return rc;
}

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);

#ifdef CONFIG_MCDI_LOGGING
	kfree(mcdi->logging_buffer);
#endif

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

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;
#ifdef CONFIG_MCDI_LOGGING
	char *buf;
#endif

	if (!mcdi)
		return;
#ifdef CONFIG_MCDI_LOGGING
	buf = mcdi->logging_buffer; /* page-sized */
#endif

	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;

#ifdef CONFIG_MCDI_LOGGING
	if (!WARN_ON_ONCE(!buf)) {
		const struct cdx_dword *frags[] = { hdr, inbuf };
		const size_t frag_len[] = { hdr_len, round_up(inlen, 4) };
		int bytes = 0;
		int i, j;

		for (j = 0; j < ARRAY_SIZE(frags); j++) {
			const struct cdx_dword *frag;

			frag = frags[j];
			for (i = 0;
			     i < frag_len[j] / 4;
			     i++) {
				/*
				 * Do not exceed the internal printk limit.
				 * The string before that is just over 70 bytes.
				 */
				if ((bytes + 75) > LOG_LINE_MAX) {
					pr_info("MCDI RPC REQ:%s \\\n", buf);
					bytes = 0;
				}
				bytes += snprintf(buf + bytes,
						  LOG_LINE_MAX - bytes, " %08x",
						  le32_to_cpu(frag[i].cdx_u32));
			}
		}

		pr_info("MCDI RPC REQ:%s\n", buf);
	}
#endif
	hdr[0].cdx_u32 |= (__force __le32)(cdx_mcdi_payload_csum(hdr, hdr_len, inbuf, inlen) <<
			 MCDI_HEADER_XFLAGS_LBN);
	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(sizeof(*wait_data), GFP_KERNEL);
	if (!wait_data)
		return -ENOMEM;

	cmd_item = kmalloc(sizeof(*cmd_item), GFP_KERNEL);
	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);
}

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);
}

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;
	}

#ifdef CONFIG_MCDI_LOGGING
	if (!WARN_ON_ONCE(!mcdi->logging_buffer)) {
		char *log = mcdi->logging_buffer;
		int i, bytes = 0;
		size_t rlen;

		WARN_ON_ONCE(resp_hdr_len % 4);

		rlen = resp_hdr_len / 4 + DIV_ROUND_UP(resp_data_len, 4);

		for (i = 0; i < rlen; i++) {
			if ((bytes + 75) > LOG_LINE_MAX) {
				pr_info("MCDI RPC RESP:%s \\\n", log);
				bytes = 0;
			}
			bytes += snprintf(log + bytes, LOG_LINE_MAX - bytes,
					  " %08x", le32_to_cpu(outbuf[i].cdx_u32));
		}

		pr_info("MCDI RPC RESP:%s\n", log);
	}
#endif

	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);
}

/**
 * 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);
	}
}
