// 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(retry_time_ms, "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:
		*val = 0xff;
		ipmi_ipmb_check_msg_done(iidev);
		break;

	case I2C_SLAVE_STOP:
		ipmi_ipmb_check_msg_done(iidev);
		break;

	case I2C_SLAVE_READ_PROCESSED:
		*val = 0xff;
		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 need to return a
		 * response to the 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 int 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);
	return IPMI_CC_NO_ERROR;
}

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

static void ipmi_ipmb_cleanup(struct ipmi_ipmb_dev *iidev)
{
	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);
}

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

	ipmi_ipmb_cleanup(iidev);
	ipmi_unregister_smi(iidev->intf);
}

static int ipmi_ipmb_probe(struct i2c_client *client)
{
	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);
		of_node_put(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_cleanup(iidev);
	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 },
	{}
};
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");
