// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/*
 * Conduit for IPMI messages to/from FSP
 *
 * Copyright 2014-2019 IBM Corp.
 */

#include <errorlog.h>
#include <fsp.h>
#include <ipmi.h>
#include <lock.h>
#include <opal-api.h>

/*
 * Under the hood, FSP IPMI component implements the KCS (Keyboard Controller
 * Style) interface
 *
 * KCS interface request message format
 *
 *    BYTE 1	 BYTE 2	       BYTE 3:N
 *  -------------------------------------
 * | NetFn/LUN |    Cmd    |    Data     |
 *  -------------------------------------
 *
 * KCS interface response message format
 *
 *    BYTE 1	 BYTE 2		BYTE 3	  BYTE 4:N
 *  ------------------------------------------------
 * | NetFn/LUN |    Cmd    |  CompCode  |   Data    |
 *  ------------------------------------------------

 */

#define FSP_IPMI_REQ_MIN_LEN	2 /* NetFn + Cmd */
#define FSP_IPMI_RESP_MIN_LEN	3 /* NetFn + Cmd + Completion code */

DEFINE_LOG_ENTRY(OPAL_RC_IPMI_REQ, OPAL_PLATFORM_ERR_EVT, OPAL_IPMI,
		 OPAL_PLATFORM_FIRMWARE, OPAL_PREDICTIVE_ERR_GENERAL,
		 OPAL_NA);
DEFINE_LOG_ENTRY(OPAL_RC_IPMI_RESP, OPAL_PLATFORM_ERR_EVT, OPAL_IPMI,
		 OPAL_PLATFORM_FIRMWARE, OPAL_PREDICTIVE_ERR_GENERAL,
		 OPAL_NA);

DEFINE_LOG_ENTRY(OPAL_RC_IPMI_DMA_ERROR_RESP, OPAL_PLATFORM_ERR_EVT, OPAL_IPMI,
		 OPAL_PLATFORM_FIRMWARE, OPAL_INFO,
		 OPAL_NA);

struct fsp_ipmi_msg {
	struct list_node	link;
	struct ipmi_msg		ipmi_msg;
};

static struct fsp_ipmi {
	struct list_head	msg_queue;
	void			*ipmi_req_buf;
	void			*ipmi_resp_buf;
	/* There can only be one outstanding request whose reference is stored
	 * in 'cur_msg' and the 'lock' protects against the concurrent updates
	 * of it through request and response. The same 'lock' also protects
	 * the list manipulation.
	 */
	struct fsp_ipmi_msg	*cur_msg;
	struct lock		lock;
} fsp_ipmi;

static int fsp_ipmi_send_request(void);

static void fsp_ipmi_cmd_done(uint8_t cmd, uint8_t netfn, uint8_t cc)
{
	struct fsp_ipmi_msg *fsp_ipmi_msg = fsp_ipmi.cur_msg;

	lock(&fsp_ipmi.lock);
	if (fsp_ipmi.cur_msg == NULL) {
		unlock(&fsp_ipmi.lock);
		return;
	}
	list_del(&fsp_ipmi_msg->link);
	fsp_ipmi.cur_msg = NULL;
	unlock(&fsp_ipmi.lock);

	ipmi_cmd_done(cmd, netfn, cc, &fsp_ipmi_msg->ipmi_msg);
}


static void fsp_ipmi_req_complete(struct fsp_msg *msg)
{
	uint8_t status = (msg->resp->word1 >> 8) & 0xff;
	uint32_t length = fsp_msg_get_data_word(msg->resp, 0);
	struct fsp_ipmi_msg *fsp_ipmi_msg = msg->user_data;
	struct ipmi_msg *ipmi_msg;

	fsp_freemsg(msg);

	if (status != FSP_STATUS_SUCCESS) {
		assert(fsp_ipmi_msg == fsp_ipmi.cur_msg);

		ipmi_msg = &fsp_ipmi_msg->ipmi_msg;

		if (length != (ipmi_msg->req_size + FSP_IPMI_REQ_MIN_LEN))
			prlog(PR_DEBUG, "IPMI: Length mismatch in req completion "
			      "(%d, %d)\n", ipmi_msg->req_size, length);

		log_simple_error(&e_info(OPAL_RC_IPMI_REQ), "IPMI: Request "
				 "failed with status:0x%02x\n", status);
		/* FSP will not send the response now, so clear the current
		 * outstanding request
		 */
		fsp_ipmi_cmd_done(ipmi_msg->cmd,
				  IPMI_NETFN_RETURN_CODE(ipmi_msg->netfn),
				  IPMI_ERR_UNSPECIFIED);

		/* Send the next request in the queue */
		fsp_ipmi_send_request();
	}
}

static int fsp_ipmi_send_request(void)
{
	uint8_t *req_buf = fsp_ipmi.ipmi_req_buf;
	struct ipmi_msg *ipmi_msg;
	struct fsp_msg *msg;
	int rc;

	if (fsp_in_rr())
		return OPAL_BUSY;

	lock(&fsp_ipmi.lock);
	/* An outstanding request is still pending */
	if (fsp_ipmi.cur_msg) {
		unlock(&fsp_ipmi.lock);
		return OPAL_SUCCESS;
	}

	fsp_ipmi.cur_msg = list_top(&fsp_ipmi.msg_queue, struct fsp_ipmi_msg,
				    link);
	unlock(&fsp_ipmi.lock);

	if (!fsp_ipmi.cur_msg)
		return OPAL_SUCCESS;

	ipmi_msg = &fsp_ipmi.cur_msg->ipmi_msg;
	prlog(PR_TRACE, "IPMI: Send request, netfn:0x%02x, cmd:0x%02x, "
	      "req_len:%d\n", ipmi_msg->netfn, ipmi_msg->cmd, ipmi_msg->req_size);

	/* KCS request message format */
	*req_buf++ = ipmi_msg->netfn;	/* BYTE 1 */
	*req_buf++ = ipmi_msg->cmd;	/* BYTE 2 */
	if (ipmi_msg->req_size)
		memcpy(req_buf, ipmi_msg->data, ipmi_msg->req_size);

	msg = fsp_mkmsg(FSP_CMD_FETCH_PLAT_DATA, 5, 0, PSI_DMA_PLAT_REQ_BUF,
			0, PSI_DMA_PLAT_RESP_BUF,
			ipmi_msg->req_size + FSP_IPMI_REQ_MIN_LEN);
	if (!msg) {
		log_simple_error(&e_info(OPAL_RC_IPMI_REQ), "IPMI: Failed to "
				 "allocate request message\n");
		fsp_ipmi_cmd_done(ipmi_msg->cmd,
				  IPMI_NETFN_RETURN_CODE(ipmi_msg->netfn),
				  IPMI_ERR_UNSPECIFIED);
		return OPAL_NO_MEM;
	}

	msg->user_data = fsp_ipmi.cur_msg;
	rc = fsp_queue_msg(msg, fsp_ipmi_req_complete);
	if (rc) {
		log_simple_error(&e_info(OPAL_RC_IPMI_REQ), "IPMI: Failed to "
				 "queue request message (%d)\n", rc);
		fsp_freemsg(msg);
		fsp_ipmi_cmd_done(ipmi_msg->cmd,
				  IPMI_NETFN_RETURN_CODE(ipmi_msg->netfn),
				  IPMI_ERR_UNSPECIFIED);
		return OPAL_INTERNAL_ERROR;
	}

	return OPAL_SUCCESS;
}

static struct ipmi_msg *fsp_ipmi_alloc_msg(size_t req_size, size_t resp_size)
{
	struct fsp_ipmi_msg *fsp_ipmi_msg;
	struct ipmi_msg *ipmi_msg;

	fsp_ipmi_msg = zalloc(sizeof(*fsp_ipmi_msg) + MAX(req_size, resp_size));
	if (!fsp_ipmi_msg)
		return NULL;

	ipmi_msg = &fsp_ipmi_msg->ipmi_msg;

	ipmi_msg->req_size = req_size;
	ipmi_msg->resp_size = resp_size;
	ipmi_msg->data = (uint8_t *)(fsp_ipmi_msg + 1);

	return ipmi_msg;
}

static void fsp_ipmi_free_msg(struct ipmi_msg *ipmi_msg)
{
	struct fsp_ipmi_msg *fsp_ipmi_msg = container_of(ipmi_msg,
			struct fsp_ipmi_msg, ipmi_msg);

	free(fsp_ipmi_msg);
}

static int fsp_ipmi_queue_msg(struct ipmi_msg *ipmi_msg)
{
	struct fsp_ipmi_msg *fsp_ipmi_msg = container_of(ipmi_msg,
			struct fsp_ipmi_msg, ipmi_msg);

	if (fsp_in_rr())
		return OPAL_BUSY;

	lock(&fsp_ipmi.lock);
	list_add_tail(&fsp_ipmi.msg_queue, &fsp_ipmi_msg->link);
	unlock(&fsp_ipmi.lock);

	return fsp_ipmi_send_request();
}

static int fsp_ipmi_queue_msg_head(struct ipmi_msg *ipmi_msg)
{
	struct fsp_ipmi_msg *fsp_ipmi_msg = container_of(ipmi_msg,
			struct fsp_ipmi_msg, ipmi_msg);

	if (fsp_in_rr())
		return OPAL_BUSY;

	lock(&fsp_ipmi.lock);
	list_add(&fsp_ipmi.msg_queue, &fsp_ipmi_msg->link);
	unlock(&fsp_ipmi.lock);

	return fsp_ipmi_send_request();
}

static int fsp_ipmi_dequeue_msg(struct ipmi_msg *ipmi_msg)
{
	struct fsp_ipmi_msg *fsp_ipmi_msg = container_of(ipmi_msg,
			struct fsp_ipmi_msg, ipmi_msg);

	lock(&fsp_ipmi.lock);
	list_del_from(&fsp_ipmi.msg_queue, &fsp_ipmi_msg->link);
	unlock(&fsp_ipmi.lock);

	return 0;
}


static bool fsp_ipmi_poll(void)
{
	/* fsp_opal_poll poller checks command responses */
	opal_run_pollers();

	return !list_empty(&fsp_ipmi.msg_queue);
}

static struct ipmi_backend fsp_ipmi_backend = {
	.alloc_msg	= fsp_ipmi_alloc_msg,
	.free_msg	= fsp_ipmi_free_msg,
	.queue_msg	= fsp_ipmi_queue_msg,
	.queue_msg_head	= fsp_ipmi_queue_msg_head,
	.dequeue_msg	= fsp_ipmi_dequeue_msg,
	.poll           = fsp_ipmi_poll,
};

static bool fsp_ipmi_rr_notify(uint32_t cmd_sub_mod,
			       struct fsp_msg *msg __unused)
{
	struct ipmi_msg *ipmi_msg;

	switch (cmd_sub_mod) {
	case FSP_RESET_START:
		return true;
	case FSP_RELOAD_COMPLETE:
		/*
		 * We will not get response for outstanding request. Send error
		 * message to caller and start sending new ipmi messages.
		 */
		if (fsp_ipmi.cur_msg) {
			ipmi_msg = &fsp_ipmi.cur_msg->ipmi_msg;
			fsp_ipmi_cmd_done(ipmi_msg->cmd,
					  IPMI_NETFN_RETURN_CODE(ipmi_msg->netfn),
					  IPMI_ERR_UNSPECIFIED);
		}
		fsp_ipmi_send_request();
		return true;
	}
	return false;
}

static struct fsp_client fsp_ipmi_client_rr = {
	.message = fsp_ipmi_rr_notify,
};

static bool fsp_ipmi_send_response(uint32_t cmd)
{
	struct fsp_msg *resp;
	int rc;

	resp = fsp_mkmsg(cmd, 0);
	if (!resp) {
		log_simple_error(&e_info(OPAL_RC_IPMI_RESP), "IPMI: Failed to "
				 "allocate response message\n");
		return false;
	}

	rc = fsp_queue_msg(resp, fsp_freemsg);
	if (rc) {
		fsp_freemsg(resp);
		log_simple_error(&e_info(OPAL_RC_IPMI_RESP), "IPMI: Failed to "
				 "queue response message\n");
		return false;
	}

	return true;
}

static bool fsp_ipmi_read_response(struct fsp_msg *msg)
{
	uint8_t *resp_buf = fsp_ipmi.ipmi_resp_buf;
	uint32_t status = fsp_msg_get_data_word(msg, 3);
	uint32_t length = fsp_msg_get_data_word(msg, 2);
	struct ipmi_msg *ipmi_msg;
	uint8_t netfn, cmd, cc;

	assert(fsp_ipmi.cur_msg);
	ipmi_msg = &fsp_ipmi.cur_msg->ipmi_msg;

	/* Response TCE token */
	assert(fsp_msg_get_data_word(msg, 1) == PSI_DMA_PLAT_RESP_BUF);

	if (status != FSP_STATUS_SUCCESS) {
		if(status == FSP_STATUS_DMA_ERROR)
			log_simple_error(&e_info(OPAL_RC_IPMI_DMA_ERROR_RESP), "IPMI: Received "
				"DMA ERROR response from FSP, this may be due to FSP "
				"is in termination state:0x%02x\n", status);
		else
			log_simple_error(&e_info(OPAL_RC_IPMI_RESP), "IPMI: FSP response "
				 "received with bad status:0x%02x\n", status);

		fsp_ipmi_cmd_done(ipmi_msg->cmd,
				  IPMI_NETFN_RETURN_CODE(ipmi_msg->netfn),
				  IPMI_ERR_UNSPECIFIED);
		return fsp_ipmi_send_response(FSP_RSP_PLAT_DATA |
					      FSP_STATUS_SUCCESS);
	}

	/* KCS response message format */
	netfn = *resp_buf++;
	cmd = *resp_buf++;
	cc = *resp_buf++;
	length -= FSP_IPMI_RESP_MIN_LEN;

	prlog(PR_TRACE, "IPMI: fsp response received, netfn:0x%02x, cmd:0x%02x,"
	      " cc:0x%02x, length:%d\n", netfn, cmd, cc, length);

	if (length > ipmi_msg->resp_size) {
		prlog(PR_DEBUG, "IPMI: Length mismatch in response (%d, %d)\n",
		      length, ipmi_msg->resp_size);
		length = ipmi_msg->resp_size; /* Truncate */
		cc = IPMI_ERR_MSG_TRUNCATED;
	}

	ipmi_msg->resp_size = length;
	if (length)
		memcpy(ipmi_msg->data, resp_buf, length);

	fsp_ipmi_cmd_done(cmd, netfn, cc);

	return fsp_ipmi_send_response(FSP_RSP_PLAT_DATA);
}

static bool fsp_ipmi_response(uint32_t cmd_sub_mod, struct fsp_msg *msg)
{
	bool rc;

	switch (cmd_sub_mod) {
	case FSP_CMD_SEND_PLAT_DATA:
		prlog(PR_TRACE, "FSP_CMD_SEND_PLAT_DATA command received\n");
		rc = fsp_ipmi_read_response(msg);
		break;
	default:
		return false;
	};

	/* If response sent successfully, pick the next request */
	if (rc == true)
		fsp_ipmi_send_request();

	return rc;
}

static struct fsp_client fsp_ipmi_client = {
	.message = fsp_ipmi_response,
};

void fsp_ipmi_init(void)
{
	fsp_tce_map(PSI_DMA_PLAT_REQ_BUF, fsp_ipmi.ipmi_req_buf,
		    PSI_DMA_PLAT_REQ_BUF_SIZE);
	fsp_tce_map(PSI_DMA_PLAT_RESP_BUF, fsp_ipmi.ipmi_resp_buf,
		    PSI_DMA_PLAT_RESP_BUF_SIZE);

	list_head_init(&fsp_ipmi.msg_queue);
	init_lock(&fsp_ipmi.lock);

	fsp_register_client(&fsp_ipmi_client, FSP_MCLASS_FETCH_SPDATA);
	fsp_register_client(&fsp_ipmi_client_rr, FSP_MCLASS_RR_EVENT);
	ipmi_register_backend(&fsp_ipmi_backend);
}
