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

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;

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

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

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

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

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