/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2013 Google Inc.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <arch/io.h>
#include <console/console.h>
#include <delay.h>
#include <stdint.h>
#include <string.h>
#include "ec.h"
#include "ec_commands.h"
#include "ec_message.h"

/* Common utilities */
void * __attribute__((weak)) crosec_get_buffer(size_t size, int req)
{
	printk(BIOS_DEBUG, "crosec_get_buffer() implementation required.\n");
	return NULL;
}

/* Dumps EC command / response data into debug output.
 *
 * @param name	Message prefix name.
 * @param cmd	Command code, or -1 to ignore cmd message.
 * @param data	Data buffer to print.
 * @param len	Length of data.
 */
static void cros_ec_dump_data(const char *name, int cmd, const uint8_t *data,
			      int len)
{
	int i;

	printk(BIOS_DEBUG, "%s: ", name);
	if (cmd != -1)
		printk(BIOS_DEBUG, "cmd=%#x: ", cmd);
	for (i = 0; i < len; i++)
		printk(BIOS_DEBUG, "%02x ", data[i]);
	printk(BIOS_DEBUG, "\n");
}

/* Calculate a simple 8-bit checksum of a data block
 *
 * @param data	Data block to checksum
 * @param size	Size of data block in bytes
 * @return checksum value (0 to 255)
 */
static int cros_ec_calc_checksum(const uint8_t *data, int size)
{
	int csum, i;

	for (i = csum = 0; i < size; i++)
		csum += data[i];
	return csum & 0xff;
}

/* Standard Chrome EC protocol, version 3 */

struct ec_command_v3 {
	struct ec_host_request header;
	uint8_t data[MSG_BYTES];
};

struct ec_response_v3 {
	struct ec_host_response header;
	uint8_t data[MSG_BYTES];
};

/**
 * Create a request packet for protocol version 3.
 *
 * @param cec_command	Command description.
 * @param cmd		Packed command bit stream.
 * @return packet size in bytes, or <0 if error.
 */
static int create_proto3_request(const struct chromeec_command *cec_command,
				 struct ec_command_v3 *cmd)
{
	struct ec_host_request *rq = &cmd->header;
	int out_bytes = cec_command->cmd_size_in + sizeof(*rq);

	/* Fail if output size is too big */
	if (out_bytes > sizeof(*cmd)) {
		printk(BIOS_ERR, "%s: Cannot send %d bytes\n", __func__,
		       cec_command->cmd_size_in);
		return -EC_RES_REQUEST_TRUNCATED;
	}

	/* Fill in request packet */
	rq->struct_version = EC_HOST_REQUEST_VERSION;
	rq->checksum = 0;
	rq->command = cec_command->cmd_code;
	rq->command_version = cec_command->cmd_version;
	rq->reserved = 0;
	rq->data_len = cec_command->cmd_size_in;

	/* Copy data after header */
	memcpy(cmd->data, cec_command->cmd_data_in, cec_command->cmd_size_in);

	/* Write checksum field so the entire packet sums to 0 */
	rq->checksum = (uint8_t)(-cros_ec_calc_checksum(
			(const uint8_t*)cmd, out_bytes));

	cros_ec_dump_data("out", rq->command, (const uint8_t *)cmd, out_bytes);

	/* Return size of request packet */
	return out_bytes;
}

/**
 * Prepare the device to receive a protocol version 3 response.
 *
 * @param cec_command	Command description.
 * @param resp		Response buffer.
 * @return maximum expected number of bytes in response, or <0 if error.
 */
static int prepare_proto3_response_buffer(
		const struct chromeec_command *cec_command,
		struct ec_response_v3 *resp)
{
	int in_bytes = cec_command->cmd_size_out + sizeof(resp->header);

	/* Fail if input size is too big */
	if (in_bytes > sizeof(*resp)) {
		printk(BIOS_ERR, "%s: Cannot receive %d bytes\n", __func__,
		       cec_command->cmd_size_out);
		return -EC_RES_RESPONSE_TOO_BIG;
	}

	/* Return expected size of response packet */
	return in_bytes;
}

/**
 * Handle a protocol version 3 response packet.
 *
 * The packet must already be stored in the response buffer.
 *
 * @param resp		Response buffer.
 * @param cec_command	Command structure to receive valid response.
 * @return number of bytes of response data, or <0 if error
 */
static int handle_proto3_response(struct ec_response_v3 *resp,
				  struct chromeec_command *cec_command)
{
	struct ec_host_response *rs = &resp->header;
	int in_bytes;
	int csum;

	cros_ec_dump_data("in-header", -1, (const uint8_t*)rs, sizeof(*rs));

	/* Check input data */
	if (rs->struct_version != EC_HOST_RESPONSE_VERSION) {
		printk(BIOS_ERR, "%s: EC response version mismatch\n", __func__);
		return -EC_RES_INVALID_RESPONSE;
	}

	if (rs->reserved) {
		printk(BIOS_ERR, "%s: EC response reserved != 0\n", __func__);
		return -EC_RES_INVALID_RESPONSE;
	}

	if (rs->data_len > sizeof(resp->data) ||
	    rs->data_len > cec_command->cmd_size_out) {
		printk(BIOS_ERR, "%s: EC returned too much data\n", __func__);
		return -EC_RES_RESPONSE_TOO_BIG;
	}

	cros_ec_dump_data("in-data", -1, resp->data, rs->data_len);

	/* Update in_bytes to actual data size */
	in_bytes = sizeof(*rs) + rs->data_len;

	/* Verify checksum */
	csum = cros_ec_calc_checksum((const uint8_t *)resp, in_bytes);
	if (csum) {
		printk(BIOS_ERR, "%s: EC response checksum invalid: 0x%02x\n",
		       __func__, csum);
		return -EC_RES_INVALID_CHECKSUM;
	}

	/* Return raw response. */
	cec_command->cmd_code = rs->result;
	cec_command->cmd_size_out = rs->data_len;
	memcpy(cec_command->cmd_data_out, resp->data, rs->data_len);

	/* Return error result, if any */
	if (rs->result) {
		printk(BIOS_ERR, "%s: EC response with error code: %d\n",
		       __func__, rs->result);
		return -(int)rs->result;
	}

	return rs->data_len;
}

static int send_command_proto3(struct chromeec_command *cec_command,
			       crosec_io_t crosec_io, void *context)
{
	int out_bytes, in_bytes;
	int rv;
	struct ec_command_v3 *cmd;
	struct ec_response_v3 *resp;

	if ((cmd = crosec_get_buffer(sizeof(*cmd), 1)) == NULL)
		return -EC_RES_ERROR;
	if ((resp = crosec_get_buffer(sizeof(*resp), 0)) == NULL)
		return -EC_RES_ERROR;

	/* Create request packet */
	out_bytes = create_proto3_request(cec_command, cmd);
	if (out_bytes < 0) {
		return out_bytes;
	}

	/* Prepare response buffer */
	in_bytes = prepare_proto3_response_buffer(cec_command, resp);
	if (in_bytes < 0) {
		return in_bytes;
	}

	rv = crosec_io(out_bytes, in_bytes, context);
	if (rv != 0) {
		printk(BIOS_ERR, "%s: failed to complete I/O: Err = %#x.\n",
		       __func__, rv >= 0 ? rv : -rv);
		return -EC_RES_ERROR;
	}

	/* Process the response */
	return handle_proto3_response(resp, cec_command);
}

static int crosec_command_proto_v3(struct chromeec_command *cec_command,
				   crosec_io_t crosec_io, void *context)
{
	int rv = send_command_proto3(cec_command, crosec_io, context);
	if (rv < 0) {
		cec_command->cmd_code = rv;
		return 1;
	}
	return 0;
}

int crosec_command_proto(struct chromeec_command *cec_command,
			 crosec_io_t crosec_io, void *context)
{
	// TODO(hungte) Detect and fallback to v2 if we need.
	return crosec_command_proto_v3(cec_command, crosec_io, context);
}
