/*
 *
 * Intel Management Engine Interface (Intel MEI) Linux driver
 * Copyright (c) 2003-2012, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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 <linux/pci.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/mei.h>

#include "mei_dev.h"
#include "hbm.h"
#include "hw-me.h"

/**
 * mei_hbm_me_cl_allocate - allocates storage for me clients
 *
 * @dev: the device structure
 *
 * returns none.
 */
static void mei_hbm_me_cl_allocate(struct mei_device *dev)
{
	struct mei_me_client *clients;
	int b;

	/* count how many ME clients we have */
	for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX)
		dev->me_clients_num++;

	if (dev->me_clients_num <= 0)
		return;

	kfree(dev->me_clients);
	dev->me_clients = NULL;

	dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n",
		dev->me_clients_num * sizeof(struct mei_me_client));
	/* allocate storage for ME clients representation */
	clients = kcalloc(dev->me_clients_num,
			sizeof(struct mei_me_client), GFP_KERNEL);
	if (!clients) {
		dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
		dev->dev_state = MEI_DEV_RESETTING;
		mei_reset(dev, 1);
		return;
	}
	dev->me_clients = clients;
	return;
}

/**
 * mei_hbm_cl_hdr - construct client hbm header
 *
 * @cl: - client
 * @hbm_cmd: host bus message command
 * @buf: buffer for cl header
 * @len: buffer length
 */
static inline
void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len)
{
	struct mei_hbm_cl_cmd *cmd = buf;

	memset(cmd, 0, len);

	cmd->hbm_cmd = hbm_cmd;
	cmd->host_addr = cl->host_client_id;
	cmd->me_addr = cl->me_client_id;
}

/**
 * same_disconn_addr - tells if they have the same address
 *
 * @file: private data of the file object.
 * @disconn: disconnection request.
 *
 * returns true if addres are same
 */
static inline
bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf)
{
	struct mei_hbm_cl_cmd *cmd = buf;
	return cl->host_client_id == cmd->host_addr &&
		cl->me_client_id == cmd->me_addr;
}


/**
 * is_treat_specially_client - checks if the message belongs
 * to the file private data.
 *
 * @cl: private data of the file object
 * @rs: connect response bus message
 *
 */
static bool is_treat_specially_client(struct mei_cl *cl,
		struct hbm_client_connect_response *rs)
{
	if (mei_hbm_cl_addr_equal(cl, rs)) {
		if (!rs->status) {
			cl->state = MEI_FILE_CONNECTED;
			cl->status = 0;

		} else {
			cl->state = MEI_FILE_DISCONNECTED;
			cl->status = -ENODEV;
		}
		cl->timer_count = 0;

		return true;
	}
	return false;
}

int mei_hbm_start_wait(struct mei_device *dev)
{
	int ret;
	if (dev->hbm_state > MEI_HBM_START)
		return 0;

	mutex_unlock(&dev->device_lock);
	ret = wait_event_interruptible_timeout(dev->wait_recvd_msg,
			dev->hbm_state == MEI_HBM_IDLE ||
			dev->hbm_state > MEI_HBM_START,
			mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
	mutex_lock(&dev->device_lock);

	if (ret <= 0 && (dev->hbm_state <= MEI_HBM_START)) {
		dev->hbm_state = MEI_HBM_IDLE;
		dev_err(&dev->pdev->dev, "waiting for mei start failed\n");
		return -ETIMEDOUT;
	}
	return 0;
}

/**
 * mei_hbm_start_req - sends start request message.
 *
 * @dev: the device structure
 */
int mei_hbm_start_req(struct mei_device *dev)
{
	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	struct hbm_host_version_request *start_req;
	const size_t len = sizeof(struct hbm_host_version_request);

	mei_hbm_hdr(mei_hdr, len);

	/* host start message */
	start_req = (struct hbm_host_version_request *)dev->wr_msg.data;
	memset(start_req, 0, len);
	start_req->hbm_cmd = HOST_START_REQ_CMD;
	start_req->host_version.major_version = HBM_MAJOR_VERSION;
	start_req->host_version.minor_version = HBM_MINOR_VERSION;

	dev->hbm_state = MEI_HBM_IDLE;
	if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
		dev_err(&dev->pdev->dev, "version message writet failed\n");
		dev->dev_state = MEI_DEV_RESETTING;
		mei_reset(dev, 1);
		return -ENODEV;
	}
	dev->hbm_state = MEI_HBM_START;
	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
	return 0;
}

/*
 * mei_hbm_enum_clients_req - sends enumeration client request message.
 *
 * @dev: the device structure
 *
 * returns none.
 */
static void mei_hbm_enum_clients_req(struct mei_device *dev)
{
	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	struct hbm_host_enum_request *enum_req;
	const size_t len = sizeof(struct hbm_host_enum_request);
	/* enumerate clients */
	mei_hbm_hdr(mei_hdr, len);

	enum_req = (struct hbm_host_enum_request *)dev->wr_msg.data;
	memset(enum_req, 0, len);
	enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;

	if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
		dev->dev_state = MEI_DEV_RESETTING;
		dev_err(&dev->pdev->dev, "enumeration request write failed.\n");
		mei_reset(dev, 1);
	}
	dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
	return;
}

/**
 * mei_hbm_prop_req - request property for a single client
 *
 * @dev: the device structure
 *
 * returns none.
 */

static int mei_hbm_prop_req(struct mei_device *dev)
{

	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	struct hbm_props_request *prop_req;
	const size_t len = sizeof(struct hbm_props_request);
	unsigned long next_client_index;
	u8 client_num;


	client_num = dev->me_client_presentation_num;

	next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX,
					  dev->me_client_index);

	/* We got all client properties */
	if (next_client_index == MEI_CLIENTS_MAX) {
		dev->hbm_state = MEI_HBM_STARTED;
		schedule_work(&dev->init_work);

		return 0;
	}

	dev->me_clients[client_num].client_id = next_client_index;
	dev->me_clients[client_num].mei_flow_ctrl_creds = 0;

	mei_hbm_hdr(mei_hdr, len);
	prop_req = (struct hbm_props_request *)dev->wr_msg.data;

	memset(prop_req, 0, sizeof(struct hbm_props_request));


	prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
	prop_req->address = next_client_index;

	if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
		dev->dev_state = MEI_DEV_RESETTING;
		dev_err(&dev->pdev->dev, "properties request write failed\n");
		mei_reset(dev, 1);

		return -EIO;
	}

	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
	dev->me_client_index = next_client_index;

	return 0;
}

/**
 * mei_hbm_stop_req_prepare - perpare stop request message
 *
 * @dev - mei device
 * @mei_hdr - mei message header
 * @data - hbm message body buffer
 */
static void mei_hbm_stop_req_prepare(struct mei_device *dev,
		struct mei_msg_hdr *mei_hdr, unsigned char *data)
{
	struct hbm_host_stop_request *req =
			(struct hbm_host_stop_request *)data;
	const size_t len = sizeof(struct hbm_host_stop_request);

	mei_hbm_hdr(mei_hdr, len);

	memset(req, 0, len);
	req->hbm_cmd = HOST_STOP_REQ_CMD;
	req->reason = DRIVER_STOP_REQUEST;
}

/**
 * mei_hbm_cl_flow_control_req - sends flow control requst.
 *
 * @dev: the device structure
 * @cl: client info
 *
 * This function returns -EIO on write failure
 */
int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl)
{
	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	const size_t len = sizeof(struct hbm_flow_control);

	mei_hbm_hdr(mei_hdr, len);
	mei_hbm_cl_hdr(cl, MEI_FLOW_CONTROL_CMD, dev->wr_msg.data, len);

	dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n",
		cl->host_client_id, cl->me_client_id);

	return mei_write_message(dev, mei_hdr, dev->wr_msg.data);
}

/**
 * mei_hbm_add_single_flow_creds - adds single buffer credentials.
 *
 * @dev: the device structure
 * @flow: flow control.
 */
static void mei_hbm_add_single_flow_creds(struct mei_device *dev,
				  struct hbm_flow_control *flow)
{
	struct mei_me_client *client;
	int i;

	for (i = 0; i < dev->me_clients_num; i++) {
		client = &dev->me_clients[i];
		if (client && flow->me_addr == client->client_id) {
			if (client->props.single_recv_buf) {
				client->mei_flow_ctrl_creds++;
				dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n",
				    flow->me_addr);
				dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n",
				    client->mei_flow_ctrl_creds);
			} else {
				BUG();	/* error in flow control */
			}
		}
	}
}

/**
 * mei_hbm_cl_flow_control_res - flow control response from me
 *
 * @dev: the device structure
 * @flow_control: flow control response bus message
 */
static void mei_hbm_cl_flow_control_res(struct mei_device *dev,
		struct hbm_flow_control *flow_control)
{
	struct mei_cl *cl = NULL;
	struct mei_cl *next = NULL;

	if (!flow_control->host_addr) {
		/* single receive buffer */
		mei_hbm_add_single_flow_creds(dev, flow_control);
		return;
	}

	/* normal connection */
	list_for_each_entry_safe(cl, next, &dev->file_list, link) {
		if (mei_hbm_cl_addr_equal(cl, flow_control)) {
			cl->mei_flow_ctrl_creds++;
			dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n",
				flow_control->host_addr, flow_control->me_addr);
			dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n",
				    cl->mei_flow_ctrl_creds);
				break;
		}
	}
}


/**
 * mei_hbm_cl_disconnect_req - sends disconnect message to fw.
 *
 * @dev: the device structure
 * @cl: a client to disconnect from
 *
 * This function returns -EIO on write failure
 */
int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl)
{
	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	const size_t len = sizeof(struct hbm_client_connect_request);

	mei_hbm_hdr(mei_hdr, len);
	mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, dev->wr_msg.data, len);

	return mei_write_message(dev, mei_hdr, dev->wr_msg.data);
}

/**
 * mei_hbm_cl_disconnect_res - disconnect response from ME
 *
 * @dev: the device structure
 * @rs: disconnect response bus message
 */
static void mei_hbm_cl_disconnect_res(struct mei_device *dev,
		struct hbm_client_connect_response *rs)
{
	struct mei_cl *cl;
	struct mei_cl_cb *pos = NULL, *next = NULL;

	dev_dbg(&dev->pdev->dev,
			"disconnect_response:\n"
			"ME Client = %d\n"
			"Host Client = %d\n"
			"Status = %d\n",
			rs->me_addr,
			rs->host_addr,
			rs->status);

	list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
		cl = pos->cl;

		if (!cl) {
			list_del(&pos->list);
			return;
		}

		dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
		if (mei_hbm_cl_addr_equal(cl, rs)) {
			list_del(&pos->list);
			if (!rs->status)
				cl->state = MEI_FILE_DISCONNECTED;

			cl->status = 0;
			cl->timer_count = 0;
			break;
		}
	}
}

/**
 * mei_hbm_cl_connect_req - send connection request to specific me client
 *
 * @dev: the device structure
 * @cl: a client to connect to
 *
 * returns -EIO on write failure
 */
int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
{
	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	const size_t len = sizeof(struct hbm_client_connect_request);

	mei_hbm_hdr(mei_hdr, len);
	mei_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, dev->wr_msg.data, len);

	return mei_write_message(dev, mei_hdr,  dev->wr_msg.data);
}

/**
 * mei_hbm_cl_connect_res - connect resposne from the ME
 *
 * @dev: the device structure
 * @rs: connect response bus message
 */
static void mei_hbm_cl_connect_res(struct mei_device *dev,
		struct hbm_client_connect_response *rs)
{

	struct mei_cl *cl;
	struct mei_cl_cb *pos = NULL, *next = NULL;

	dev_dbg(&dev->pdev->dev,
			"connect_response:\n"
			"ME Client = %d\n"
			"Host Client = %d\n"
			"Status = %d\n",
			rs->me_addr,
			rs->host_addr,
			rs->status);

	/* if WD or iamthif client treat specially */

	if (is_treat_specially_client(&dev->wd_cl, rs)) {
		dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
		mei_watchdog_register(dev);

		return;
	}

	if (is_treat_specially_client(&dev->iamthif_cl, rs)) {
		dev->iamthif_state = MEI_IAMTHIF_IDLE;
		return;
	}
	list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {

		cl = pos->cl;
		if (!cl) {
			list_del(&pos->list);
			return;
		}
		if (pos->fop_type == MEI_FOP_IOCTL) {
			if (is_treat_specially_client(cl, rs)) {
				list_del(&pos->list);
				cl->status = 0;
				cl->timer_count = 0;
				break;
			}
		}
	}
}


/**
 * mei_hbm_fw_disconnect_req - disconnect request initiated by me
 *  host sends disoconnect response
 *
 * @dev: the device structure.
 * @disconnect_req: disconnect request bus message from the me
 */
static void mei_hbm_fw_disconnect_req(struct mei_device *dev,
		struct hbm_client_connect_request *disconnect_req)
{
	struct mei_cl *cl, *next;
	const size_t len = sizeof(struct hbm_client_connect_response);

	list_for_each_entry_safe(cl, next, &dev->file_list, link) {
		if (mei_hbm_cl_addr_equal(cl, disconnect_req)) {
			dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
					disconnect_req->host_addr,
					disconnect_req->me_addr);
			cl->state = MEI_FILE_DISCONNECTED;
			cl->timer_count = 0;
			if (cl == &dev->wd_cl)
				dev->wd_pending = false;
			else if (cl == &dev->iamthif_cl)
				dev->iamthif_timer = 0;

			/* prepare disconnect response */
			mei_hbm_hdr(&dev->wr_ext_msg.hdr, len);
			mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_RES_CMD,
					 dev->wr_ext_msg.data, len);
			break;
		}
	}
}


/**
 * mei_hbm_version_is_supported - checks whether the driver can
 *     support the hbm version of the device
 *
 * @dev: the device structure
 * returns true if driver can support hbm version of the device
 */
bool mei_hbm_version_is_supported(struct mei_device *dev)
{
	return	(dev->version.major_version < HBM_MAJOR_VERSION) ||
		(dev->version.major_version == HBM_MAJOR_VERSION &&
		 dev->version.minor_version <= HBM_MINOR_VERSION);
}

/**
 * mei_hbm_dispatch - bottom half read routine after ISR to
 * handle the read bus message cmd processing.
 *
 * @dev: the device structure
 * @mei_hdr: header of bus message
 */
void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
{
	struct mei_bus_message *mei_msg;
	struct mei_me_client *me_client;
	struct hbm_host_version_response *version_res;
	struct hbm_client_connect_response *connect_res;
	struct hbm_client_connect_response *disconnect_res;
	struct hbm_client_connect_request *disconnect_req;
	struct hbm_flow_control *flow_control;
	struct hbm_props_response *props_res;
	struct hbm_host_enum_response *enum_res;

	/* read the message to our buffer */
	BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf));
	mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
	mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;

	switch (mei_msg->hbm_cmd) {
	case HOST_START_RES_CMD:
		version_res = (struct hbm_host_version_response *)mei_msg;

		dev_dbg(&dev->pdev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n",
				HBM_MAJOR_VERSION, HBM_MINOR_VERSION,
				version_res->me_max_version.major_version,
				version_res->me_max_version.minor_version);

		if (version_res->host_version_supported) {
			dev->version.major_version = HBM_MAJOR_VERSION;
			dev->version.minor_version = HBM_MINOR_VERSION;
		} else {
			dev->version.major_version =
				version_res->me_max_version.major_version;
			dev->version.minor_version =
				version_res->me_max_version.minor_version;
		}

		if (!mei_hbm_version_is_supported(dev)) {
			dev_warn(&dev->pdev->dev, "hbm version mismatch: stopping the driver.\n");

			dev->hbm_state = MEI_HBM_STOP;
			mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr,
						dev->wr_msg.data);
			mei_write_message(dev, &dev->wr_msg.hdr,
					dev->wr_msg.data);

			return;
		}

		if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
		    dev->hbm_state == MEI_HBM_START) {
			dev->init_clients_timer = 0;
			mei_hbm_enum_clients_req(dev);
		} else {
			dev_err(&dev->pdev->dev, "reset: wrong host start response\n");
			mei_reset(dev, 1);
			return;
		}

		wake_up_interruptible(&dev->wait_recvd_msg);
		dev_dbg(&dev->pdev->dev, "host start response message received.\n");
		break;

	case CLIENT_CONNECT_RES_CMD:
		connect_res = (struct hbm_client_connect_response *) mei_msg;
		mei_hbm_cl_connect_res(dev, connect_res);
		dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
		wake_up(&dev->wait_recvd_msg);
		break;

	case CLIENT_DISCONNECT_RES_CMD:
		disconnect_res = (struct hbm_client_connect_response *) mei_msg;
		mei_hbm_cl_disconnect_res(dev, disconnect_res);
		dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
		wake_up(&dev->wait_recvd_msg);
		break;

	case MEI_FLOW_CONTROL_CMD:
		flow_control = (struct hbm_flow_control *) mei_msg;
		mei_hbm_cl_flow_control_res(dev, flow_control);
		dev_dbg(&dev->pdev->dev, "client flow control response message received.\n");
		break;

	case HOST_CLIENT_PROPERTIES_RES_CMD:
		props_res = (struct hbm_props_response *)mei_msg;
		me_client = &dev->me_clients[dev->me_client_presentation_num];

		if (props_res->status || !dev->me_clients) {
			dev_err(&dev->pdev->dev, "reset: properties response hbm wrong status.\n");
			mei_reset(dev, 1);
			return;
		}

		if (me_client->client_id != props_res->address) {
			dev_err(&dev->pdev->dev, "reset: host properties response address mismatch\n");
			mei_reset(dev, 1);
			return;
		}

		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
		    dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
			dev_err(&dev->pdev->dev, "reset: unexpected properties response\n");
			mei_reset(dev, 1);

			return;
		}

		me_client->props = props_res->client_properties;
		dev->me_client_index++;
		dev->me_client_presentation_num++;

		/* request property for the next client */
		mei_hbm_prop_req(dev);

		break;

	case HOST_ENUM_RES_CMD:
		enum_res = (struct hbm_host_enum_response *) mei_msg;
		memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
		if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
		    dev->hbm_state == MEI_HBM_ENUM_CLIENTS) {
				dev->init_clients_timer = 0;
				dev->me_client_presentation_num = 0;
				dev->me_client_index = 0;
				mei_hbm_me_cl_allocate(dev);
				dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES;

				/* first property reqeust */
				mei_hbm_prop_req(dev);
		} else {
			dev_err(&dev->pdev->dev, "reset: unexpected enumeration response hbm.\n");
			mei_reset(dev, 1);
			return;
		}
		break;

	case HOST_STOP_RES_CMD:

		if (dev->hbm_state != MEI_HBM_STOP)
			dev_err(&dev->pdev->dev, "unexpected stop response hbm.\n");
		dev->dev_state = MEI_DEV_DISABLED;
		dev_info(&dev->pdev->dev, "reset: FW stop response.\n");
		mei_reset(dev, 1);
		break;

	case CLIENT_DISCONNECT_REQ_CMD:
		/* search for client */
		disconnect_req = (struct hbm_client_connect_request *)mei_msg;
		mei_hbm_fw_disconnect_req(dev, disconnect_req);
		break;

	case ME_STOP_REQ_CMD:

		dev->hbm_state = MEI_HBM_STOP;
		mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr,
					dev->wr_ext_msg.data);
		break;
	default:
		BUG();
		break;

	}
}

