// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
// Copyright 2022 IBM Corp.

#define pr_fmt(fmt) "PLDM: " fmt

#include <bitmap.h>
#include <cpu.h>
#include <opal.h>
#include <opal-msg.h>
#include <stdio.h>
#include <string.h>
#include <debug_descriptor.h>
#include <libpldm/fru.h>
#include <libpldm/platform.h>
#include <libpldm/platform_oem_ibm.h>
#include <libpldm/state_set.h>
#include <libpldm/utils.h>
#include "pldm.h"

struct pldm_type {
	const char *name;
	int pldm_type_id;
	ver32_t version;

	struct list_head commands;
	struct list_node link;
};

struct pldm_cmd {
	const char *name;
	int pldm_cmd_id;

	int (*handler)(const struct pldm_rx_data *rx);

	struct list_node link; /* link in the msg type's command list */
};

/*
 * Send a response with just a completion code and no payload
 */
static int cc_resp(const struct pldm_rx_data *rx, uint8_t type,
			uint8_t command, uint8_t cc)
{
	size_t data_size = PLDM_MSG_SIZE(uint8_t);
	struct pldm_tx_data *tx;
	int rc;

	/* Encode the cc response */
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size;
	tx->tag_owner = true;
	tx->msg_tag = rx->msg_tag;

	encode_cc_only_resp(rx->hdrinf.instance,
			    type,
			    command,
			    cc,
			    (struct pldm_msg *)tx->data);

	rc = pldm_mctp_message_tx(tx);
	if (rc) {
		prlog(PR_ERR, "Failed to send response message containing only cc, "
			      "rc = %d, cc = %d\n", rc, cc);
		free(tx);
		return OPAL_HARDWARE;
	}

	free(tx);
	return OPAL_SUCCESS;
}

/*
 * PLDM Type / Command wrangling.
 */
LIST_HEAD(pldm_type_list);

static const struct pldm_type *find_type(int type_id)
{
	struct pldm_type *iter;

	list_for_each(&pldm_type_list, iter, link) {
		if (iter->pldm_type_id == type_id)
			return iter;
	}

	return NULL;
}

static const struct pldm_cmd *find_cmd(const struct pldm_type *type, int cmd)
{
	struct pldm_cmd *iter;

	list_for_each(&type->commands, iter, link)
		if (iter->pldm_cmd_id == cmd)
			return iter;

	return NULL;
}

static void add_type(struct pldm_type *new_type)
{
	assert(new_type->pldm_type_id < 32); /* limited by GetPLDMTypes */
	assert(!find_type(new_type->pldm_type_id));

	list_head_init(&new_type->commands);
	list_add_tail(&pldm_type_list, &new_type->link);

	prlog(PR_DEBUG, "Registered type %s (%d)\n",
	      new_type->name, new_type->pldm_type_id);
}

static void add_cmd(struct pldm_type *type, struct pldm_cmd *new_cmd)
{
	assert(new_cmd->pldm_cmd_id < 256); /* limited by GetPLDMCommands */
	assert(new_cmd->handler);
	assert(!find_cmd(type, new_cmd->pldm_cmd_id));

	list_add_tail(&type->commands, &new_cmd->link);
	prlog(PR_DEBUG, "Registered command %s (%d) under %s\n",
		new_cmd->name, new_cmd->pldm_cmd_id, type->name);
}

/*
 * PLDM Base commands support
 */
static struct pldm_type pldm_base_type = {
	.name = "base",
	.pldm_type_id = PLDM_BASE,
	.version = { 0xF1, 0xF0, 0xF0, 0x00 },
};

/*
 * GetTID command (0x02)
 * The GetTID command is used to retrieve the present Terminus ID (TID)
 * setting for a PLDM Terminus.
 */
static int base_get_tid_handler(const struct pldm_rx_data *rx)
{
	size_t data_size = PLDM_MSG_SIZE(struct pldm_get_tid_resp);
	struct pldm_tx_data *tx;
	int rc;

	/* create a PLDM response message for GetTID */
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size;
	tx->tag_owner = true;
	tx->msg_tag = rx->msg_tag;

	rc = encode_get_tid_resp(rx->hdrinf.instance,
				 PLDM_SUCCESS,
				 HOST_TID,
				 (struct pldm_msg *)tx->data);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode GetTID Error, rc: %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		free(tx);
		return OPAL_PARAMETER;
	}

	rc = pldm_mctp_message_tx(tx);
	if (rc) {
		prlog(PR_ERR, "Failed to send GetTID response, rc = %d\n", rc);
		free(tx);
		return OPAL_HARDWARE;
	}

	free(tx);
	return OPAL_SUCCESS;
}

static struct pldm_cmd pldm_base_get_tid = {
	.name = "PLDM_GET_TID",
	.pldm_cmd_id = PLDM_GET_TID,
	.handler = base_get_tid_handler,
};

/*
 * GetPLDMTypes (0x04)
 * The GetPLDMTypes command can be used to discover the PLDM type
 * capabilities supported by a PLDM terminus and to get a list of the
 * PLDM types that are supported.
 */
static int base_get_types_handler(const struct pldm_rx_data *rx)
{
	size_t data_size = PLDM_MSG_SIZE(struct pldm_get_types_resp);
	bitmap_elem_t type_map[BITMAP_ELEMS(PLDM_MAX_TYPES)];
	struct pldm_tx_data *tx;
	struct pldm_type *iter;
	int rc;

	/* build the supported type list from the registered type
	 * handlers
	 */
	memset(type_map, 0, sizeof(type_map));
	list_for_each(&pldm_type_list, iter, link)
		bitmap_set_bit(type_map, iter->pldm_type_id);

	for (int i = 0; i < BITMAP_ELEMS(PLDM_MAX_TYPES); i++)
		type_map[i] = cpu_to_le64(type_map[i]);

	/* create a PLDM response message for GetPLDMTypes */
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size;
	tx->tag_owner = true;
	tx->msg_tag = rx->msg_tag;

	rc = encode_get_types_resp(rx->hdrinf.instance,
				   PLDM_SUCCESS,
				   (bitfield8_t *)type_map,
				   (struct pldm_msg *)tx->data);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode GetPLDMTypes Error, rc: %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		free(tx);
		return OPAL_PARAMETER;
	}

	rc = pldm_mctp_message_tx(tx);
	if (rc) {
		prlog(PR_ERR, "Failed to send GetPLDMTypes response, rc = %d\n", rc);
		free(tx);
		return OPAL_HARDWARE;
	}

	free(tx);
	return OPAL_SUCCESS;
}

static struct pldm_cmd pldm_base_get_types = {
	.name = "PLDM_GET_PLDM_TYPES",
	.pldm_cmd_id = PLDM_GET_PLDM_TYPES,
	.handler = base_get_types_handler,
};

/*
 * Extended error codes defined for the Base command set.
 */
#define INVALID_DATA_TRANSFER_HANDLE           0x80
#define INVALID_TRANSFER_OPERATION_FLAG        0x81
#define INVALID_PLDM_TYPE_IN_REQUEST_DATA      0x83
#define INVALID_PLDM_VERSION_IN_REQUEST_DATA   0x84

/*
 * GetPLDMCommands (0x05)
 * The GetPLDMCommands command can be used to discover the PLDM command
 * capabilities supported by aPLDM terminus for a specific PLDM Type and
 * version as a responder.
 */
static int base_get_commands_handler(const struct pldm_rx_data *rx)
{
	size_t data_size = PLDM_MSG_SIZE(struct pldm_get_commands_resp);
	bitmap_elem_t cmd_map[BITMAP_ELEMS(PLDM_MAX_CMDS_PER_TYPE)];
	const struct pldm_type *type;
	const struct pldm_cmd *iter;
	struct pldm_tx_data *tx;
	size_t payload_len;
	ver32_t version;
	uint8_t type_id;
	int rc;

	payload_len = rx->msg_len - sizeof(struct pldm_msg_hdr);
	rc = decode_get_commands_req(rx->msg, payload_len,
				     &type_id, &version);
	if (rc) {
		prlog(PR_ERR, "Failed to decode GetPLDMCommands request, rc = %d", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		return OPAL_INTERNAL_ERROR;
	}

	type = find_type(type_id);
	if (!type) {
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			INVALID_PLDM_TYPE_IN_REQUEST_DATA);
		return OPAL_PARAMETER;
	}

	if (memcmp(&type->version, &version, sizeof(version))) {
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			INVALID_PLDM_VERSION_IN_REQUEST_DATA);
		return OPAL_PARAMETER;
	}

	/* build the supported type list from the registered type
	 * handlers
	 */
	memset(cmd_map, 0, sizeof(cmd_map));
	list_for_each(&type->commands, iter, link)
		bitmap_set_bit(cmd_map, iter->pldm_cmd_id);

	/* fix the endian */
	for (int i = 0; i < BITMAP_ELEMS(PLDM_MAX_CMDS_PER_TYPE); i++)
		cmd_map[i] = cpu_to_le64(cmd_map[i]);

	/* create a PLDM response message for GetPLDMCommands */
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size;
	tx->tag_owner = true;
	tx->msg_tag = rx->msg_tag;

	rc = encode_get_commands_resp(rx->hdrinf.instance,
				      PLDM_SUCCESS,
				      (bitfield8_t *)cmd_map,
				      (struct pldm_msg *)tx->data);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode GetPLDMCommands Error, rc: %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		free(tx);
		return OPAL_PARAMETER;
	}

	/* send PLDM message over MCTP */
	rc = pldm_mctp_message_tx(tx);
	if (rc) {
		prlog(PR_ERR, "Failed to send GetPLDMCommands response, rc = %d\n", rc);
		return OPAL_HARDWARE;
		free(tx);
	}

	free(tx);
	return OPAL_SUCCESS;
}

static struct pldm_cmd pldm_base_get_commands = {
	.name = "PLDM_GET_PLDM_COMMANDS",
	.pldm_cmd_id = PLDM_GET_PLDM_COMMANDS,
	.handler = base_get_commands_handler,
};

/*
 * GetPLDMVersion (0x03)
 * The GetPLDMVersion command can be used to retrieve the PLDM base
 * specification versions that the PLDM terminus supports, as well as
 * the PLDM Type specification versions supported for each PLDM Type.
 */
static int base_get_version_handler(const struct pldm_rx_data *rx)
{
	uint32_t version_data[2];
	size_t data_size = PLDM_MSG_SIZE(struct pldm_get_version_resp) + sizeof(version_data);
	const struct pldm_type *type;
	struct pldm_tx_data *tx;
	uint8_t type_id, opflag;
	uint32_t xfer_handle;
	size_t payload_len;
	int rc;

	payload_len = rx->msg_len - sizeof(struct pldm_msg_hdr);
	rc = decode_get_version_req(rx->msg, payload_len,
				    &xfer_handle,
				    &opflag,
				    &type_id);
	if (rc) {
		prlog(PR_ERR, "Failed to decode GetPLDMVersion request, rc = %d", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		return OPAL_INTERNAL_ERROR;
	}

	/* reject multipart requests */
	if (opflag != PLDM_GET_FIRSTPART) {
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			INVALID_TRANSFER_OPERATION_FLAG);
		return OPAL_PARAMETER;
	}

	type = find_type(type_id);
	if (!type) {
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			INVALID_PLDM_TYPE_IN_REQUEST_DATA);
		return OPAL_PARAMETER;
	}

	/* pack a scratch buffer with our version(s) and CRC32 the lot */
	memcpy(&version_data[0], &type->version, 4);

	version_data[1] = cpu_to_le32(crc32(&type->version, 4));

	/* create a PLDM response for GetPLDMVersion */
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size;
	tx->tag_owner = true;
	tx->msg_tag = rx->msg_tag;

	rc = encode_get_version_resp(rx->hdrinf.instance,
				     PLDM_SUCCESS,
				     0x0, /* no handle */
				     PLDM_START_AND_END,
				     (ver32_t *) version_data,
				     sizeof(version_data),
				     (struct pldm_msg *)tx->data);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode GetPLDMVersion Error, rc: %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		free(tx);
		return OPAL_PARAMETER;
	}

	/* send PLDM message over MCTP */
	rc = pldm_mctp_message_tx(tx);
	if (rc) {
		prlog(PR_ERR, "Failed to send GetPLDMVersion response, rc = %d\n", rc);
		free(tx);
		return OPAL_HARDWARE;
	}

	free(tx);

	/* BMC has certainly rebooted, so reload the PDRs */
	return pldm_platform_reload_pdrs();
}

static struct pldm_cmd pldm_base_get_version = {
	.name = "PLDM_GET_PLDM_VERSION",
	.pldm_cmd_id = PLDM_GET_PLDM_VERSION,
	.handler = base_get_version_handler,
};

/*
 * PLDM Platform commands support
 */
static struct pldm_type pldm_platform_type = {
	.name = "platform",
	.pldm_type_id = PLDM_PLATFORM,
};

#define MIN_WATCHDOG_TIMEOUT_SEC 15

/*
 * SetEventReceiver (0x04)
 * The SetEventReceiver command is used to set the address of the Event
 * Receiver into a terminus that generates event messages. It is also
 * used to globally enable or disable whether event messages are
 * generated from the terminus.
 */
static int platform_set_event_receiver_handler(const struct pldm_rx_data *rx)
{
	uint8_t event_message_global_enable, transport_protocol_type;
	uint8_t event_receiver_address_info, cc = PLDM_SUCCESS;
	uint16_t heartbeat_timer;
	int rc = OPAL_SUCCESS;

	/* decode SetEventReceiver request data */
	rc = decode_set_event_receiver_req(
				rx->msg,
				PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
				&event_message_global_enable,
				&transport_protocol_type,
				&event_receiver_address_info,
				&heartbeat_timer);
	if (rc) {
		prlog(PR_ERR, "Failed to decode SetEventReceiver request, rc = %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		return OPAL_INTERNAL_ERROR;
	}

	/* invoke the appropriate callback handler */
	prlog(PR_DEBUG, "%s - event_message_global_enable: %d, "
			"transport_protocol_type: %d "
			"event_receiver_address_info: %d "
			"heartbeat_timer: %d\n",
			__func__,
			event_message_global_enable,
			transport_protocol_type,
			event_receiver_address_info,
			heartbeat_timer);

	if (event_message_global_enable !=
		PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {

		prlog(PR_ERR, "%s - invalid value for message global enable received: %d\n",
			      __func__, event_message_global_enable);
		cc = PLDM_PLATFORM_ENABLE_METHOD_NOT_SUPPORTED;
	}

	if (heartbeat_timer < MIN_WATCHDOG_TIMEOUT_SEC) {
		prlog(PR_ERR, "%s - BMC requested watchdog timeout that's too small: %d\n",
			      __func__, heartbeat_timer);
		cc = PLDM_PLATFORM_HEARTBEAT_FREQUENCY_TOO_HIGH;
	} else {
		/* set the internal watchdog period to what BMC indicated */
		watchdog_period_sec = heartbeat_timer;
	}

	/* send the response to BMC */
	cc_resp(rx, PLDM_PLATFORM, PLDM_SET_EVENT_RECEIVER, cc);

	/* no error happened above, so arm the watchdog and set the default timeout */
	if (cc == PLDM_SUCCESS)
		watchdog_armed = true;

	return rc;
}

static struct pldm_cmd pldm_platform_set_event_receiver = {
	.name = "PLDM_SET_EVENT_RECEIVER",
	.pldm_cmd_id = PLDM_SET_EVENT_RECEIVER,
	.handler = platform_set_event_receiver_handler,
};

/*
 * PlatformEventMessage (0x10)
 * PLDM Event Messages are sent as PLDM request messages to the Event
 * Receiver using the PlatformEventMessage command.
 */
static int platform_event_message(const struct pldm_rx_data *rx)
{
	size_t data_size = PLDM_MSG_SIZE(struct pldm_platform_event_message_resp);
	struct pldm_bios_attribute_update_event_req *request;
	uint8_t format_version, tid, event_class;
	uint8_t *bios_attribute_handles;
	uint8_t cc = PLDM_SUCCESS;
	size_t event_data_offset;
	struct pldm_tx_data *tx;
	int rc, i;

	/* decode PlatformEventMessage request data */
	rc = decode_platform_event_message_req(
				rx->msg,
				sizeof(struct pldm_platform_event_message_req),
				&format_version,
				&tid,
				&event_class,
				&event_data_offset);
	if (rc) {
		prlog(PR_ERR, "Failed to decode PlatformEventMessage request, rc = %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		return OPAL_INTERNAL_ERROR;
	}

	prlog(PR_DEBUG, "%s - format_version: %d, "
			"tid: %d "
			"event_class: %d "
			"event_data: 0x%lx\n",
			__func__,
			format_version, tid,
			event_class, event_data_offset);

	/* we don't support any other event than the PDR Repo Changed event */
	if ((event_class != PLDM_PDR_REPOSITORY_CHG_EVENT) &&
	    (event_class != PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE)) {
		prlog(PR_ERR, "%s - Invalid event class %d in platform event handler\n",
			      __func__, event_class);
		cc = PLDM_ERROR;
	}

	/* Encode the platform event request */
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size;
	tx->tag_owner = true;
	tx->msg_tag = rx->msg_tag;

	rc = encode_platform_event_message_resp(
					rx->hdrinf.instance,
					cc,
					PLDM_EVENT_NO_LOGGING,
					(struct pldm_msg *)tx->data);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode PlatformEventMessage Error, rc: %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		free(tx);
		return OPAL_PARAMETER;
	}

	/* send PLDM message over MCTP */
	rc = pldm_mctp_message_tx(tx);
	if (rc) {
		prlog(PR_ERR, "Failed to send PlatformEventMessage response, rc = %d\n", rc);
		free(tx);
		return OPAL_HARDWARE;
	}

	/* invoke the appropriate callback handler */
	if (event_class == PLDM_PDR_REPOSITORY_CHG_EVENT) {
		free(tx);
		return pldm_platform_reload_pdrs();
	}

	/* When the attribute value changes for any BIOS attribute, then
	 * PlatformEventMessage command with OEM event type
	 * PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE is send to
	 * host with the list of BIOS attribute handles.
	 */
	if (event_class == PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE) {
		request = (struct pldm_bios_attribute_update_event_req *)rx->msg->payload;
		bios_attribute_handles = (uint8_t *)request->bios_attribute_handles;

		prlog(PR_DEBUG, "%s - OEM_EVENT_BIOS_ATTRIBUTE_UPDATE, handles: %d\n",
				__func__, request->num_handles);

		/* list of BIOS attribute handles */
		for (i = 0; i < request->num_handles; i++) {
			prlog(PR_DEBUG, "%s - OEM_EVENT_BIOS_ATTRIBUTE_UPDATE: handle(%d): %d\n",
					__func__, i, *bios_attribute_handles);
			bios_attribute_handles += sizeof(uint16_t);
		}
	}

	free(tx);
	return OPAL_SUCCESS;
}

static struct pldm_cmd pldm_platform_event_message = {
	.name = "PLDM_PLATFORM_EVENT_MESSAGE",
	.pldm_cmd_id = PLDM_PLATFORM_EVENT_MESSAGE,
	.handler = platform_event_message,
};

/*
 * GetStateSensorReadings (0x21)
 * The GetStateSensorReadings command can return readings for multiple
 * state sensors (a PLDM State Sensor that returns more than one set of
 * state information is called a composite state sensor).
 */
static int platform_get_state_sensor_readings(const struct pldm_rx_data *rx)
{
	bitfield8_t sensor_rearm;
	struct pldm_tx_data *tx;
	uint16_t sensor_id;
	uint8_t reserved;
	size_t data_size;
	int rc;

	get_sensor_state_field sensor_state = {
		.sensor_op_state = PLDM_SENSOR_UNKNOWN,
		.present_state = 0,
		.previous_state = 0,
		.event_state = 0
	};

	/* decode GetStateSensorReadings request data */
	rc = decode_get_state_sensor_readings_req(
				rx->msg,
				PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
				&sensor_id,
				&sensor_rearm,
				&reserved);
	if (rc) {
		prlog(PR_ERR, "Failed to decode GetStateSensorReadings request, rc = %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		return OPAL_INTERNAL_ERROR;
	}

	prlog(PR_DEBUG, "%s - sensor_id: %d, sensor_rearm: %x\n",
			__func__, sensor_id, sensor_rearm.byte);

	/* send state sensor reading response */
	data_size = sizeof(struct pldm_msg_hdr) +
		    sizeof(struct pldm_get_state_sensor_readings_resp) +
		    (sizeof(get_sensor_state_field) * 1);

	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size;
	tx->tag_owner = true;
	tx->msg_tag = rx->msg_tag;

	rc = encode_get_state_sensor_readings_resp(
					rx->hdrinf.instance,
					PLDM_SUCCESS,
					1, /* sensor count of 1 */
					&sensor_state,
					(struct pldm_msg *)tx->data);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode GetStateSensorReadings response Error, rc: %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		free(tx);
		return OPAL_PARAMETER;
	}

	/* send PLDM message over MCTP */
	rc = pldm_mctp_message_tx(tx);
	if (rc) {
		prlog(PR_ERR, "Failed to send GetStateSensorReadings response, rc = %d\n", rc);
		free(tx);
		return OPAL_HARDWARE;
	}

	free(tx);
	return OPAL_SUCCESS;
}

static struct pldm_cmd pldm_platform_get_state_sensor_readings = {
	.name = "PLDM_GET_STATE_SENSOR_READINGS",
	.pldm_cmd_id = PLDM_GET_STATE_SENSOR_READINGS,
	.handler = platform_get_state_sensor_readings,
};

#define SOFT_OFF		0x00
#define SOFT_REBOOT		0x01
#define CHASSIS_PWR_DOWN	0x00
#define DEFAULT_CHIP_ID		0

/*
 * SetStateEffecterStates (0x39)
 * The SetStateEffecterStates command is used to set the state of one
 * or more effecters within a PLDM State Effecter.
 */
static int platform_set_state_effecter_states_handler(const struct pldm_rx_data *rx)
{
	set_effecter_state_field field[8];
	uint8_t comp_effecter_count;
	uint16_t effecter_id;
	int rc, i;

	/* decode SetStateEffecterStates request data */
	rc = decode_set_state_effecter_states_req(
				rx->msg,
				PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES,
				&effecter_id,
				&comp_effecter_count,
				field);
	if (rc) {
		prlog(PR_ERR, "Failed to decode SetStateEffecterStates request, rc = %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		return OPAL_INTERNAL_ERROR;
	}

	/* invoke the appropriate callback handler */
	prlog(PR_DEBUG, "%s - effecter_id: %d, comp_effecter_count: %d\n",
			__func__, effecter_id, comp_effecter_count);

	for (i = 0; i < comp_effecter_count; i++) {
		/* other set_request not supported */
		if (field[i].set_request != PLDM_REQUEST_SET) {
			prlog(PR_ERR, "Got invalid set request 0x%x in "
				      "SetStateEffecterStates request\n",
				      field[i].set_request);
			cc_resp(rx, rx->hdrinf.pldm_type,
				rx->hdrinf.command,
				PLDM_PLATFORM_INVALID_STATE_VALUE);
			return OPAL_PARAMETER;
		}

		switch (field[i].effecter_state) {
		case PLDM_SW_TERM_GRACEFUL_SHUTDOWN_REQUESTED:
		case PLDM_STATE_SET_SYS_POWER_STATE_OFF_SOFT_GRACEFUL:
			prlog(PR_NOTICE, "Soft shutdown requested\n");
			cc_resp(rx, PLDM_PLATFORM,
				PLDM_SET_STATE_EFFECTER_STATES,
				PLDM_SUCCESS);

			if (opal_booting() && platform.cec_power_down) {
				prlog(PR_NOTICE, "Host not up, shutting down now\n");
				platform.cec_power_down(CHASSIS_PWR_DOWN);
			} else {
				opal_queue_msg(OPAL_MSG_SHUTDOWN,
					       NULL, NULL,
					       cpu_to_be64(SOFT_OFF));
			}

			break;

		case PLDM_SW_TERM_GRACEFUL_RESTART_REQUESTED:
			prlog(PR_NOTICE, "Soft reboot requested\n");
			cc_resp(rx, PLDM_PLATFORM,
				PLDM_SET_STATE_EFFECTER_STATES,
				PLDM_SUCCESS);

			if (opal_booting() && platform.cec_reboot) {
				prlog(PR_NOTICE, "Host not up, rebooting now\n");
				platform.cec_reboot();
			} else {
				opal_queue_msg(OPAL_MSG_SHUTDOWN,
					       NULL, NULL,
					       cpu_to_be64(SOFT_REBOOT));
			}

			break;

		case PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET:
		case PLDM_STATE_SET_BOOT_RESTART_CAUSE_HARD_RESET:
			prlog(PR_NOTICE, "OCC reset requested\n");
			cc_resp(rx, PLDM_PLATFORM,
				PLDM_SET_STATE_EFFECTER_STATES,
				PLDM_SUCCESS);

			/* invoke the appropriate callback handler */
			prd_occ_reset(DEFAULT_CHIP_ID); /* FIXME, others chip ? */
			break;

		default:
			prlog(PR_ERR, "Got invalid effecter state 0x%x in "
				      "SetStateEffecterStates request\n",
				      field[i].effecter_state);
			cc_resp(rx, rx->hdrinf.pldm_type,
				rx->hdrinf.command,
				PLDM_PLATFORM_INVALID_STATE_VALUE);
			return OPAL_PARAMETER;
		}
	}

	return OPAL_SUCCESS;
}

static struct pldm_cmd pldm_platform_set_state_effecter_states = {
	.name = "PLDM_SET_STATE_EFFECTER_STATES",
	.pldm_cmd_id = PLDM_SET_STATE_EFFECTER_STATES,
	.handler = platform_set_state_effecter_states_handler,
};

/*
 * GetPDR (0x51)
 * The GetPDR command is used to retrieve individual PDRs from a PDR
 * Repository. The record is identified by the PDR recordHandle value
 * that is passed in the request.
 */
static int platform_get_pdr_handle(const struct pldm_rx_data *rx)
{
	uint32_t data_transfer_handle, pdr_data_size = 0;
	uint32_t record_handle, next_record_handle;
	uint16_t request_count, record_change_number;
	uint8_t transfer_op_flag, *pdr_data = NULL;
	size_t payload_len, data_size;
	struct pldm_tx_data *tx;
	int rc;

	payload_len = rx->msg_len - sizeof(struct pldm_msg_hdr);
	rc = decode_get_pdr_req(rx->msg,
				payload_len,
				&record_handle,
				&data_transfer_handle,
				&transfer_op_flag,
				&request_count,
				&record_change_number);
	if (rc) {
		prlog(PR_ERR, "Failed to decode GetPDR request, rc = %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		return OPAL_INTERNAL_ERROR;
	}

	if (data_transfer_handle != 0) {
		/* We don't support multipart transfers */
		prlog(PR_ERR, "Got invalid data transfer handle 0x%x in GetPDR request\n",
			      data_transfer_handle);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			PLDM_PLATFORM_INVALID_DATA_TRANSFER_HANDLE);
		return OPAL_PARAMETER;
	}

	if (transfer_op_flag != PLDM_GET_FIRSTPART) {
		prlog(PR_ERR, "Got invalid transfer op flag 0x%x in GetPDR request\n",
			      transfer_op_flag);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			PLDM_PLATFORM_INVALID_TRANSFER_OPERATION_FLAG);
		return OPAL_PARAMETER;
	}

	if (record_change_number != 0) {
		prlog(PR_ERR, "Got invalid record change number 0x%x in GetPDR request\n",
			      record_change_number);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			PLDM_PLATFORM_INVALID_RECORD_CHANGE_NUMBER);
		return OPAL_PARAMETER;
	}

	/* find PDR record by record handle */
	prlog(PR_INFO, "BMC requesting PDR handle %d\n", record_handle);

	rc = pldm_platform_pdr_find_record(record_handle,
					   &pdr_data,
					   &pdr_data_size,
					   &next_record_handle);
	if (rc) {
		prlog(PR_ERR, "Got invalid record handle 0x%x in GetPDR request\n",
			      record_handle);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			PLDM_PLATFORM_INVALID_RECORD_HANDLE);
		return OPAL_PARAMETER;
	}

	/* create a PLDM response message for GetPDR */
	data_size = sizeof(struct pldm_msg_hdr) +
		    sizeof(struct pldm_get_pdr_resp) +
		    pdr_data_size;

	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size - 1;
	tx->tag_owner = true;
	tx->msg_tag = rx->msg_tag;

	rc = encode_get_pdr_resp(rx->hdrinf.instance,
				 PLDM_SUCCESS,
				 next_record_handle,
				 0, /* No remaining data */
				 PLDM_START_AND_END,
				 pdr_data_size,
				 pdr_data,
				 0, /* CRC not used for START_AND_END */
				 (struct pldm_msg *)tx->data);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode GetPDR Error, rc: %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		free(tx);
		return OPAL_PARAMETER;
	}

	/* send PLDM message over MCTP */
	rc = pldm_mctp_message_tx(tx);
	if (rc) {
		prlog(PR_ERR, "Failed to send GetPDR response, rc = %d\n", rc);
		free(tx);
		return OPAL_HARDWARE;
	}

	free(tx);
	return OPAL_SUCCESS;
}

static struct pldm_cmd pldm_platform_get_pdr = {
	.name = "PLDM_GET_PDR",
	.pldm_cmd_id = PLDM_GET_PDR,
	.handler = platform_get_pdr_handle,
};

/*
 * PLDM Fru commands support
 */
static struct pldm_type pldm_fru_type = {
	.name = "fru",
	.pldm_type_id = PLDM_FRU,
};

/* currently we support version 1.0 of fru table */
#define SUPPORTED_FRU_VERSION_MAJOR 1
#define SUPPORTED_FRU_VERSION_MINOR 0

/* Used by the metadata request handler for the value of
 * FRUTableMaximumSize
 * 0 means SetFRURecordTable command is not supported (see DSP 0257
 * v1.0.0 Table 9)
 */
#define FRU_TABLE_MAX_SIZE_UNSUPPORTED 0

/*
 * GetFRURecordTableMetadata (0X01)
 * The GetFRURecordTableMetadata command is used to get the FRU Record
 * Table metadata information that includes the FRU Record major
 * version, the FRU Record minor version, the size of the largest FRU
 * Record data, total length of the FRU Record Table, total number of
 * FRU Record Data structures, and the integrity checksum on the FRU
 * Record Table data.
 */
static int fru_get_record_table_metadata_handler(const struct pldm_rx_data *rx)
{
	size_t data_size = PLDM_MSG_SIZE(struct pldm_get_fru_record_table_metadata_resp);
	uint16_t total_record_set_identifiers, total_table_records;
	uint32_t fru_table_length;
	struct pldm_tx_data *tx;
	int rc;

	/*
	 * GetFRURecordTableMetadata requests
	 * don't have any payload, so no need to decode them
	 */

	/* add specific fru record */
	pldm_fru_set_local_table(&fru_table_length,
				 &total_record_set_identifiers,
				 &total_table_records);

	/* create a PLDM response message for GetFRURecordTableMetadata */
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size;
	tx->tag_owner = true;
	tx->msg_tag = rx->msg_tag;

	rc = encode_get_fru_record_table_metadata_resp(
				rx->hdrinf.instance,
				PLDM_SUCCESS,
				SUPPORTED_FRU_VERSION_MAJOR,
				SUPPORTED_FRU_VERSION_MINOR,
				FRU_TABLE_MAX_SIZE_UNSUPPORTED,
				fru_table_length,
				total_record_set_identifiers,
				total_table_records,
				0, // checksum, not calculated
				(struct pldm_msg *)tx->data);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode GetFRURecordTableMetadata Error, rc: %d\n", rc);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command, PLDM_ERROR);
		free(tx);
		return OPAL_PARAMETER;
	}

	/* send PLDM message over MCTP */
	rc = pldm_mctp_message_tx(tx);
	if (rc) {
		prlog(PR_ERR, "Failed to send GetFRURecordTableMetadata response, rc = %d\n", rc);
		free(tx);
		return OPAL_HARDWARE;
	}

	free(tx);
	return OPAL_SUCCESS;
}

static struct pldm_cmd pldm_fru_get_record_table_metadata = {
	.name = "PLDM_GET_FRU_RECORD_TABLE_METADATA",
	.pldm_cmd_id = PLDM_GET_FRU_RECORD_TABLE_METADATA,
	.handler = fru_get_record_table_metadata_handler,
};

int pldm_responder_handle_request(struct pldm_rx_data *rx)
{
	const struct pldm_type *type;
	const struct pldm_cmd *cmd;

	prlog(PR_INFO, "Receive PLDM request from BMC, type: 0x%x, command: 0x%x\n",
			rx->hdrinf.pldm_type, rx->hdrinf.command);

	type = find_type(rx->hdrinf.pldm_type);
	if (!type) {
		prlog(PR_ERR, "Type not supported, type: 0x%x\n",
			      rx->hdrinf.pldm_type);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			PLDM_ERROR_INVALID_PLDM_TYPE);
		return OPAL_UNSUPPORTED;
	}

	cmd = find_cmd(type, rx->hdrinf.command);
	if (!cmd) {
		prlog(PR_ERR, "Command not supported, type: 0x%x, command: 0x%x\n",
			      rx->hdrinf.pldm_type, rx->hdrinf.command);
		cc_resp(rx, rx->hdrinf.pldm_type,
			rx->hdrinf.command,
			PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
		return OPAL_UNSUPPORTED;
	}

	return cmd->handler(rx);
}

int pldm_responder_init(void)
{
	/* Register mandatory commands we'll respond to - DSP0240 */
	add_type(&pldm_base_type);
	add_cmd(&pldm_base_type, &pldm_base_get_tid);
	add_cmd(&pldm_base_type, &pldm_base_get_types);
	add_cmd(&pldm_base_type, &pldm_base_get_commands);
	add_cmd(&pldm_base_type, &pldm_base_get_version);

	/* Register platform commands we'll respond to - DSP0248 */
	add_type(&pldm_platform_type);
	add_cmd(&pldm_platform_type, &pldm_platform_set_event_receiver);
	add_cmd(&pldm_platform_type, &pldm_platform_event_message);
	add_cmd(&pldm_platform_type, &pldm_platform_get_state_sensor_readings);
	add_cmd(&pldm_platform_type, &pldm_platform_set_state_effecter_states);
	add_cmd(&pldm_platform_type, &pldm_platform_get_pdr);

	/* Register fru commands we'll respond to - DSP0257 */
	add_type(&pldm_fru_type);
	add_cmd(&pldm_fru_type, &pldm_fru_get_record_table_metadata);

	return OPAL_SUCCESS;
}
