// SPDX-License-Identifier: GPL-2.0

/*
 * Driver to talk to a remote management controller on IPMB.
 */

#include <linux/acpi.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/semaphore.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/ipmi_msgdefs.h>
#include <linux/ipmi_smi.h>

#define DEVICE_NAME "ipmi-ipmb"

static int bmcaddr = 0x20;
module_param(bmcaddr, int, 0644);
MODULE_PARM_DESC(bmcaddr, "Address to use for BMC.");

static unsigned int retry_time_ms = 250;
module_param(retry_time_ms, uint, 0644);
MODULE_PARM_DESC(max_retries, "Timeout time between retries, in milliseconds.");

static unsigned int max_retries = 1;
module_param(max_retries, uint, 0644);
MODULE_PARM_DESC(max_retries, "Max resends of a command before timing out.");

/* Add room for the two slave addresses, two checksums, and rqSeq. */
#define IPMB_MAX_MSG_LEN (IPMI_MAX_MSG_LENGTH + 5)

struct ipmi_ipmb_dev {
	struct ipmi_smi *intf;
	struct i2c_client *client;
	struct i2c_client *slave;

	struct ipmi_smi_handlers handlers;

	bool ready;

	u8 curr_seq;

	u8 bmcaddr;
	u32 retry_time_ms;
	u32 max_retries;

	struct ipmi_smi_msg *next_msg;
	struct ipmi_smi_msg *working_msg;

	/* Transmit thread. */
	struct task_struct *thread;
	struct semaphore wake_thread;
	struct semaphore got_rsp;
	spinlock_t lock;
	bool stopping;

	u8 xmitmsg[IPMB_MAX_MSG_LEN];
	unsigned int xmitlen;

	u8 rcvmsg[IPMB_MAX_MSG_LEN];
	unsigned int rcvlen;
	bool overrun;
};

static bool valid_ipmb(struct ipmi_ipmb_dev *iidev)
{
	u8 *msg = iidev->rcvmsg;
	u8 netfn;

	if (iidev->overrun)
		return false;

	/* Minimum message size. */
	if (iidev->rcvlen < 7)
		return false;

	/* Is it a response? */
	netfn = msg[1] >> 2;
	if (netfn & 1) {
		/* Response messages have an added completion code. */
		if (iidev->rcvlen < 8)
			return false;
	}

	if (ipmb_checksum(msg, 3) != 0)
		return false;
	if (ipmb_checksum(msg + 3, iidev->rcvlen - 3) != 0)
		return false;

	return true;
}

static void ipmi_ipmb_check_msg_done(struct ipmi_ipmb_dev *iidev)
{
	struct ipmi_smi_msg *imsg = NULL;
	u8 *msg = iidev->rcvmsg;
	bool is_cmd;
	unsigned long flags;

	if (iidev->rcvlen == 0)
		return;
	if (!valid_ipmb(iidev))
		goto done;

	is_cmd = ((msg[1] >> 2) & 1) == 0;

	if (is_cmd) {
		/* Ignore commands until we are up. */
		if (!iidev->ready)
			goto done;

		/* It's a command, allocate a message for it. */
		imsg = ipmi_alloc_smi_msg();
		if (!imsg)
			goto done;
		imsg->type = IPMI_SMI_MSG_TYPE_IPMB_DIRECT;
		imsg->data_size = 0;
	} else {
		spin_lock_irqsave(&iidev->lock, flags);
		if (iidev->working_msg) {
			u8 seq = msg[4] >> 2;
			bool xmit_rsp = (iidev->working_msg->data[0] >> 2) & 1;

			/*
			 * Responses should carry the sequence we sent
			 * them with.  If it's a transmitted response,
			 * ignore it.  And if the message hasn't been
			 * transmitted, ignore it.
			 */
			if (!xmit_rsp && seq == iidev->curr_seq) {
				iidev->curr_seq = (iidev->curr_seq + 1) & 0x3f;

				imsg = iidev->working_msg;
				iidev->working_msg = NULL;
			}
		}
		spin_unlock_irqrestore(&iidev->lock, flags);
	}

	if (!imsg)
		goto done;

	if (imsg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) {
		imsg->rsp[0] = msg[1]; /* NetFn/LUN */
		/*
		 * Keep the source address, rqSeq.  Drop the trailing
		 * checksum.
		 */
		memcpy(imsg->rsp + 1, msg + 3, iidev->rcvlen - 4);
		imsg->rsp_size = iidev->rcvlen - 3;
	} else {
		imsg->rsp[0] = msg[1]; /* NetFn/LUN */
		/*
		 * Skip the source address, rqSeq.  Drop the trailing
		 * checksum.
		 */
		memcpy(imsg->rsp + 1, msg + 5, iidev->rcvlen - 6);
		imsg->rsp_size = iidev->rcvlen - 5;
	}
	ipmi_smi_msg_received(iidev->intf, imsg);
	if (!is_cmd)
		up(&iidev->got_rsp);

done:
	iidev->overrun = false;
	iidev->rcvlen = 0;
}

/*
 * The IPMB protocol only supports i2c writes so there is no need to
 * support I2C_SLAVE_READ* events, except to know if the other end has
 * issued a read without going to stop mode.
 */
static int ipmi_ipmb_slave_cb(struct i2c_client *client,
			      enum i2c_slave_event event, u8 *val)
{
	struct ipmi_ipmb_dev *iidev = i2c_get_clientdata(client);

	switch (event) {
	case I2C_SLAVE_WRITE_REQUESTED:
		ipmi_ipmb_check_msg_done(iidev);
		/*
		 * First byte is the slave address, to ease the checksum
		 * calculation.
		 */
		iidev->rcvmsg[0] = client->addr << 1;
		iidev->rcvlen = 1;
		break;

	case I2C_SLAVE_WRITE_RECEIVED:
		if (iidev->rcvlen >= sizeof(iidev->rcvmsg))
			iidev->overrun = true;
		else
			iidev->rcvmsg[iidev->rcvlen++] = *val;
		break;

	case I2C_SLAVE_READ_REQUESTED:
	case I2C_SLAVE_STOP:
		ipmi_ipmb_check_msg_done(iidev);
		break;

	case I2C_SLAVE_READ_PROCESSED:
		break;
	}

	return 0;
}

static void ipmi_ipmb_send_response(struct ipmi_ipmb_dev *iidev,
				    struct ipmi_smi_msg *msg, u8 cc)
{
	if ((msg->data[0] >> 2) & 1) {
		/*
		 * It's a response being sent, we needto return a
		 * response response.  Fake a send msg command
		 * response with channel 0.  This will always be ipmb
		 * direct.
		 */
		msg->data[0] = (IPMI_NETFN_APP_REQUEST | 1) << 2;
		msg->data[3] = IPMI_SEND_MSG_CMD;
		msg->data[4] = cc;
		msg->data_size = 5;
	}
	msg->rsp[0] = msg->data[0] | (1 << 2);
	if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) {
		msg->rsp[1] = msg->data[1];
		msg->rsp[2] = msg->data[2];
		msg->rsp[3] = msg->data[3];
		msg->rsp[4] = cc;
		msg->rsp_size = 5;
	} else {
		msg->rsp[1] = msg->data[1];
		msg->rsp[2] = cc;
		msg->rsp_size = 3;
	}
	ipmi_smi_msg_received(iidev->intf, msg);
}

static void ipmi_ipmb_format_for_xmit(struct ipmi_ipmb_dev *iidev,
				      struct ipmi_smi_msg *msg)
{
	if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) {
		iidev->xmitmsg[0] = msg->data[1];
		iidev->xmitmsg[1] = msg->data[0];
		memcpy(iidev->xmitmsg + 4, msg->data + 2, msg->data_size - 2);
		iidev->xmitlen = msg->data_size + 2;
	} else {
		iidev->xmitmsg[0] = iidev->bmcaddr;
		iidev->xmitmsg[1] = msg->data[0];
		iidev->xmitmsg[4] = 0;
		memcpy(iidev->xmitmsg + 5, msg->data + 1, msg->data_size - 1);
		iidev->xmitlen = msg->data_size + 4;
	}
	iidev->xmitmsg[3] = iidev->slave->addr << 1;
	if (((msg->data[0] >> 2) & 1) == 0)
		/* If it's a command, put in our own sequence number. */
		iidev->xmitmsg[4] = ((iidev->xmitmsg[4] & 0x03) |
				     (iidev->curr_seq << 2));

	/* Now add on the final checksums. */
	iidev->xmitmsg[2] = ipmb_checksum(iidev->xmitmsg, 2);
	iidev->xmitmsg[iidev->xmitlen] =
		ipmb_checksum(iidev->xmitmsg + 3, iidev->xmitlen - 3);
	iidev->xmitlen++;
}

static int ipmi_ipmb_thread(void *data)
{
	struct ipmi_ipmb_dev *iidev = data;

	while (!kthread_should_stop()) {
		long ret;
		struct i2c_msg i2c_msg;
		struct ipmi_smi_msg *msg = NULL;
		unsigned long flags;
		unsigned int retries = 0;

		/* Wait for a message to send */
		ret = down_interruptible(&iidev->wake_thread);
		if (iidev->stopping)
			break;
		if (ret)
			continue;

		spin_lock_irqsave(&iidev->lock, flags);
		if (iidev->next_msg) {
			msg = iidev->next_msg;
			iidev->next_msg = NULL;
		}
		spin_unlock_irqrestore(&iidev->lock, flags);
		if (!msg)
			continue;

		ipmi_ipmb_format_for_xmit(iidev, msg);

retry:
		i2c_msg.len = iidev->xmitlen - 1;
		if (i2c_msg.len > 32) {
			ipmi_ipmb_send_response(iidev, msg,
						IPMI_REQ_LEN_EXCEEDED_ERR);
			continue;
		}

		i2c_msg.addr = iidev->xmitmsg[0] >> 1;
		i2c_msg.flags = 0;
		i2c_msg.buf = iidev->xmitmsg + 1;

		/* Rely on i2c_transfer for a barrier. */
		iidev->working_msg = msg;

		ret = i2c_transfer(iidev->client->adapter, &i2c_msg, 1);

		if ((msg->data[0] >> 2) & 1) {
			/*
			 * It's a response, nothing will be returned
			 * by the other end.
			 */

			iidev->working_msg = NULL;
			ipmi_ipmb_send_response(iidev, msg,
						ret < 0 ? IPMI_BUS_ERR : 0);
			continue;
		}
		if (ret < 0) {
			iidev->working_msg = NULL;
			ipmi_ipmb_send_response(iidev, msg, IPMI_BUS_ERR);
			continue;
		}

		/* A command was sent, wait for its response. */
		ret = down_timeout(&iidev->got_rsp,
				   msecs_to_jiffies(iidev->retry_time_ms));

		/*
		 * Grab the message if we can.  If the handler hasn't
		 * already handled it, the message will still be there.
		 */
		spin_lock_irqsave(&iidev->lock, flags);
		msg = iidev->working_msg;
		iidev->working_msg = NULL;
		spin_unlock_irqrestore(&iidev->lock, flags);

		if (!msg && ret) {
			/*
			 * If working_msg is not set and we timed out,
			 * that means the message grabbed by
			 * check_msg_done before we could grab it
			 * here.  Wait again for check_msg_done to up
			 * the semaphore.
			 */
			down(&iidev->got_rsp);
		} else if (msg && ++retries <= iidev->max_retries) {
			spin_lock_irqsave(&iidev->lock, flags);
			iidev->working_msg = msg;
			spin_unlock_irqrestore(&iidev->lock, flags);
			goto retry;
		}

		if (msg)
			ipmi_ipmb_send_response(iidev, msg, IPMI_TIMEOUT_ERR);
	}

	if (iidev->next_msg)
		/* Return an unspecified error. */
		ipmi_ipmb_send_response(iidev, iidev->next_msg, 0xff);

	return 0;
}

static int ipmi_ipmb_start_processing(void *send_info,
				      struct ipmi_smi *new_intf)
{
	struct ipmi_ipmb_dev *iidev = send_info;

	iidev->intf = new_intf;
	iidev->ready = true;
	return 0;
}

static void ipmi_ipmb_stop_thread(struct ipmi_ipmb_dev *iidev)
{
	if (iidev->thread) {
		struct task_struct *t = iidev->thread;

		iidev->thread = NULL;
		iidev->stopping = true;
		up(&iidev->wake_thread);
		up(&iidev->got_rsp);
		kthread_stop(t);
	}
}

static void ipmi_ipmb_shutdown(void *send_info)
{
	struct ipmi_ipmb_dev *iidev = send_info;

	ipmi_ipmb_stop_thread(iidev);
}

static void ipmi_ipmb_sender(void *send_info,
			     struct ipmi_smi_msg *msg)
{
	struct ipmi_ipmb_dev *iidev = send_info;
	unsigned long flags;

	spin_lock_irqsave(&iidev->lock, flags);
	BUG_ON(iidev->next_msg);

	iidev->next_msg = msg;
	spin_unlock_irqrestore(&iidev->lock, flags);

	up(&iidev->wake_thread);
}

static void ipmi_ipmb_request_events(void *send_info)
{
	/* We don't fetch events here. */
}

static int ipmi_ipmb_remove(struct i2c_client *client)
{
	struct ipmi_ipmb_dev *iidev = i2c_get_clientdata(client);

	if (iidev->slave) {
		i2c_slave_unregister(iidev->slave);
		if (iidev->slave != iidev->client)
			i2c_unregister_device(iidev->slave);
	}
	iidev->slave = NULL;
	iidev->client = NULL;
	ipmi_ipmb_stop_thread(iidev);

	ipmi_unregister_smi(iidev->intf);

	return 0;
}

static int ipmi_ipmb_probe(struct i2c_client *client,
			   const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct ipmi_ipmb_dev *iidev;
	struct device_node *slave_np;
	struct i2c_adapter *slave_adap = NULL;
	struct i2c_client *slave = NULL;
	int rv;

	iidev = devm_kzalloc(&client->dev, sizeof(*iidev), GFP_KERNEL);
	if (!iidev)
		return -ENOMEM;

	if (of_property_read_u8(dev->of_node, "bmcaddr", &iidev->bmcaddr) != 0)
		iidev->bmcaddr = bmcaddr;
	if (iidev->bmcaddr == 0 || iidev->bmcaddr & 1) {
		/* Can't have the write bit set. */
		dev_notice(&client->dev,
			   "Invalid bmc address value %2.2x\n", iidev->bmcaddr);
		return -EINVAL;
	}

	if (of_property_read_u32(dev->of_node, "retry-time",
				 &iidev->retry_time_ms) != 0)
		iidev->retry_time_ms = retry_time_ms;

	if (of_property_read_u32(dev->of_node, "max-retries",
				 &iidev->max_retries) != 0)
		iidev->max_retries = max_retries;

	slave_np = of_parse_phandle(dev->of_node, "slave-dev", 0);
	if (slave_np) {
		slave_adap = of_get_i2c_adapter_by_node(slave_np);
		if (!slave_adap) {
			dev_notice(&client->dev,
				   "Could not find slave adapter\n");
			return -EINVAL;
		}
	}

	iidev->client = client;

	if (slave_adap) {
		struct i2c_board_info binfo;

		memset(&binfo, 0, sizeof(binfo));
		strscpy(binfo.type, "ipmb-slave", I2C_NAME_SIZE);
		binfo.addr = client->addr;
		binfo.flags = I2C_CLIENT_SLAVE;
		slave = i2c_new_client_device(slave_adap, &binfo);
		i2c_put_adapter(slave_adap);
		if (IS_ERR(slave)) {
			rv = PTR_ERR(slave);
			dev_notice(&client->dev,
				   "Could not allocate slave device: %d\n", rv);
			return rv;
		}
		i2c_set_clientdata(slave, iidev);
	} else {
		slave = client;
	}
	i2c_set_clientdata(client, iidev);
	slave->flags |= I2C_CLIENT_SLAVE;

	rv = i2c_slave_register(slave, ipmi_ipmb_slave_cb);
	if (rv)
		goto out_err;
	iidev->slave = slave;
	slave = NULL;

	iidev->handlers.flags = IPMI_SMI_CAN_HANDLE_IPMB_DIRECT;
	iidev->handlers.start_processing = ipmi_ipmb_start_processing;
	iidev->handlers.shutdown = ipmi_ipmb_shutdown;
	iidev->handlers.sender = ipmi_ipmb_sender;
	iidev->handlers.request_events = ipmi_ipmb_request_events;

	spin_lock_init(&iidev->lock);
	sema_init(&iidev->wake_thread, 0);
	sema_init(&iidev->got_rsp, 0);

	iidev->thread = kthread_run(ipmi_ipmb_thread, iidev,
				    "kipmb%4.4x", client->addr);
	if (IS_ERR(iidev->thread)) {
		rv = PTR_ERR(iidev->thread);
		dev_notice(&client->dev,
			   "Could not start kernel thread: error %d\n", rv);
		goto out_err;
	}

	rv = ipmi_register_smi(&iidev->handlers,
			       iidev,
			       &client->dev,
			       iidev->bmcaddr);
	if (rv)
		goto out_err;

	return 0;

out_err:
	if (slave && slave != client)
		i2c_unregister_device(slave);
	ipmi_ipmb_remove(client);
	return rv;
}

#ifdef CONFIG_OF
static const struct of_device_id of_ipmi_ipmb_match[] = {
	{ .type = "ipmi", .compatible = DEVICE_NAME },
	{},
};
MODULE_DEVICE_TABLE(of, of_ipmi_ipmb_match);
#else
#define of_ipmi_ipmb_match NULL
#endif

static const struct i2c_device_id ipmi_ipmb_id[] = {
	{ DEVICE_NAME, 0 },
	{},
};
MODULE_DEVICE_TABLE(i2c, ipmi_ipmb_id);

static struct i2c_driver ipmi_ipmb_driver = {
	.class		= I2C_CLASS_HWMON,
	.driver = {
		.name = DEVICE_NAME,
		.of_match_table = of_ipmi_ipmb_match,
	},
	.probe		= ipmi_ipmb_probe,
	.remove		= ipmi_ipmb_remove,
	.id_table	= ipmi_ipmb_id,
};
module_i2c_driver(ipmi_ipmb_driver);

MODULE_AUTHOR("Corey Minyard");
MODULE_DESCRIPTION("IPMI IPMB driver");
MODULE_LICENSE("GPL v2");
